Initial set of Fabric switch test cases

Change-Id: I86fd2b67d3b773aa496f5ef61f1e1fdf51fd9925
diff --git a/Fabric/Doc/CONTRIBUTING.md b/Fabric/Doc/CONTRIBUTING.md
new file mode 100644
index 0000000..bbab966
--- /dev/null
+++ b/Fabric/Doc/CONTRIBUTING.md
@@ -0,0 +1,196 @@
+# How Can I Contribute?
+
+We're always willing to accept good pull requests (PRs). In case you're stuck for ideas on where to start, here are some ideas to get you started.
+
+## Add Missing Test Cases
+
+We welcome any patch that adds a missing test (or improves an existing one, for that matter). In this regard, while they make for heavy reading, the [OpenFlow Specifications](https://www.opennetworking.org/sdn-resources/onf-specifications/openflow) are likely the best places to start. Once you have an idea of a test you'd like to implement just check the [Adding Your Own Test Cases](#adding-or-modifying-tests) section below.
+
+## Bug Fixes
+
+Humans will inevitably write buggy software. If you spot a bug in either a test cases or another element of the framework then either [submit a fix](https://github.com/floodlight/oftest/pulls) or [file a bug](https://github.com/floodlight/oftest/issues).
+
+## Add New Features
+
+Need to modify OFTest to fit a personal need or business requirement? Great! If you think it'll be useful to anyone else then submit a PR for review.
+
+## Documentation & Other Changes
+
+Using OFTest in a unique way? Finding OFTest difficult to set up and wanting to help others avoid your issues? Finding yourself annoyed by a typo in some code/documentation? Submit a pull request!
+
+---
+
+# Making Changes
+
+## Adding or Modifying Tests
+
+OFTest itself uses the `unittest` library, which is part of the Python Standard Library. This means there are some requirements for tests written for OFTest:
+
+ * Each new test case should be its own class.
+ * All tests must inherit from `unittest.TestCase` or an existing test. Most tests will inherit from `oftest.base_tests.SimpleDataPlane`.
+ * Tests must also provide a `runTest` function, which will act as the main routine for all test cases. This is also how OFTest discovers tests.
+ * Tests should use the `unittest` assert cases, defined [here](https://docs.python.org/2/library/unittest.html#assert-methods), as they provide more information to the user about issues that standard the standard `assert`.
+ * Tests may provide a `setUp` and/or `tearDown` function. These will be automatically called by the test framework before/after calling `runTest` respectively. If overriding an existing test be sure to call the super class' `setUp` or `tearDown` functions.
+
+We suggest you look at `basic.py` as a starting point for writing new tests. It's also worth noting these conventions:
+
+ * The first line of the doc string for a file and for a test class is displayed in the list command. Please keep it clear and under 50 characters.
+
+### Coding Style
+
+OFTest uses the Python Standard Style Guide, or [PEP-8](http://www.python.org/dev/peps/pep-0008/). Please ensure all changes abide by this standard.
+
+In addition, when adding new tests, the test file names should be lowercase with underscores and short, meaningful names. Test case class names should be CamelCased and use similarly short, meaningful names.
+
+## Documentation
+
+Any additional documentation added to the repository should be in [GitHub-flavored Markdown](https://help.github.com/articles/github-flavored-markdown/).
+
+---
+
+# Architecture
+
+The directory structure is currently:
+
+    <oftest>
+        `
+        |-- oft
+        |-- docs
+        |-- src
+        |   `-- python
+        |       `-- oftest
+        |-- tests
+        |   `-- test cases for OpenFlow 1.0
+        |-- tests-1.x
+        |   `-- test cases for a specific version
+        `-- tools
+
+## Base Test Types
+
+Once installed  the components of OFTest are available via import of submodules of `oftest`. Typically, new tests will be written as subclasses of one of the two following tests:
+
+ * The basic protocol test, `SimpleProtocol`, is used for tests that require only communication with the switch over the controller interface
+ * The basic dataplane test, `SimpleDataPlane` is used for tests that require both communication with the switch and the ability to send/receive packets to/from OpenFlow ports.
+
+SimpleProtocol and SimpleDataPlane are defined in `oftest/base_tests.py`.
+
+### Simple Protocol
+
+The essential object provided by inheritance from `SimpleProtocol` (and from `SimpleDataPlane` which is a subclass of `SimpleProtocol`) is `self.controller`. The `setUp` routine ensures a connection has been made to the SUT prior to returning. Thus, in `runTest` you can send messages across the control interface simply by invoking methods of this control object. These may be sent unacknowledged or done as transactions (which are based on the XID in the OpenFlow header):
+
+    import oftest.base_tests as base_tests
+
+    class MyTest(basic.SimpleProtocol):
+    ... # Inside your runTest:
+        self.controller.message_send(msg)   # Unacknowledged
+        self.controller.transact(request)   # Transaction based on XID
+
+### SimpleDataPlane
+
+`SimpleDataPlane` inherits from `SimpleProtocol`, so you get the controller object as well as the dataplane object, `self.dataplane`.
+
+Sending packets into the switch is done with the `send` member:
+
+    import basic
+
+    class MyDPTest(basic.SimpleDataPlane):
+    ... # Inside your runTest:
+        pkt = simple_tcp_packet()
+        self.dataplane.send(port, str(pkt))
+
+Packets can be received in the following ways:
+
+ * Non-blocking poll:
+
+        (port, pkt, timestamp) = self.dataplane.poll()
+
+ * Blocking poll:
+
+        (port, pkt, timestamp) = self.dataplane.poll(timeout=1)
+
+    For the calls to poll, you may specify a port number in which case only packets received on that port will be returned.
+
+        (port, pkt, timestamp) = self.dataplane.poll(port_number=2, timeout=1)
+
+ * Register a handler:
+
+        self.dataplane.register(handler)
+
+### DataPlaneOnly
+
+Occasionally, it is convenient to be able to send a packet into a switch without connecting to the controller. The DataPlaneOnly class is the parent that allows you to do this. It instantiates a dataplane, but not a controller object. The classes `PacketOnly` and `PacketOnlyTagged` inherit from `DataPlaneOnly` and send packets into the switch.
+
+## Messages
+
+The OpenFlow protocol is represented by a collection of objects inside the `oftest.message` module. In general, each message has its own class. All messages have a header member and data members specific to the message. Certain variable length data is treated specially and is described (TBD).
+
+Here are some examples:
+
+    import oftest.message as message
+    ...
+    request = message.echo_request()
+
+`request` is now an `echo_request` object and can be sent via `self.controller`.transact for example.
+
+    msg = message.packet_out()
+
+`msg` is now a packet_out object. `msg.data` holds the variable length packet data.
+
+    msg.data = str(some_packet_data)
+
+This brings us to one of the important variable length data members, the action list. Each action type has its own class. The action list is also a class with an `add` method which takes an action object.
+
+    import oftest.action as action
+    ...
+    act = action.action_output()   # Create a new output action object
+    act.port = egress_port         # Set the action's parameter(s)
+    msg.actions.add(act)           # The packet out message has an action list member
+
+Another key data class is the match object. TBD: Fill this out.
+
+TBD: Add information about stats objects.
+
+## Packets
+
+OFTest uses [Scapy](http://www.secdev.org/projects/scapy/) for managing packet data, although you may not need to use it directly. In the example below, we use the function `simple_tcp_packet` from `testutils.py` to generate a packet. The the parse function `packet_to_flow_match` is called to generate a flow match based on the packet.
+
+    from testutils import *
+    import oftest.parse as parse
+    import ofp
+    ...
+    pkt = simple_tcp_packet()
+    match = parse.packet_to_flow_match(pkt)
+    match.wildcards &= ~ofp.OFPFW_IN_PORT
+
+This introduces the low level module `ofp`. This provides the base definitions from which OpenFlow messages are inherited and basic OpenFlow defines such as `OFPFW_IN_PORT`. Most enums defined in `openflow.h` are available in this module.
+
+---
+
+# Tips & Tricks
+
+## Making Your Tests Configurable
+
+As described in the [README](README.md#passing-parameters-to-tests), you can test for these parameters by importing `testutils.py` and using the function:
+
+    my_key1 = testutils.test_param_get(self.config, 'key1')
+
+The `config` parameter is the global configuration structure copied into the base tests cases (and usually available in each test file). The routine returns `None` if the key was not assigned in the command line; otherwise it returns the value assigned (`17` in this example).
+
+Note that any test may look at these parameters, so use some care in choosing your parameter keys.
+
+## Adding Support for a New Platform
+
+As described in the [README](README.md#platforms), OFTest provides a method for specifying how packets should be sent/received to/from the switch. The "config files" that enable this are known as "platforms".
+
+You can add your own platform, say `gp104`, by adding a file `gp104.py` to the
+`platforms` directory. This file should define the function `platform_config_update`. This can be enabled using the `--platform=gp104` parameter on the command line. You can also use the `--platform-dir` option to change which directory is searched.
+
+IMPORTANT: The file should define a function `platform_config_update` which takes a configuration dictionary as an argument and updates it for the current run. In particular, it should set up `config["port_map"]` with the proper map from OpenFlow port numbers to OpenFlow interface names.
+
+## Troubleshooting
+
+Normally, all debug output goes to the file `oft.log` in the current directory. You can force the output to appear on the terminal (and set the most verbose debug level) with these parameters added to the oft command:
+
+    --verbose --log-file=[path/to/logfile]
+
+---
diff --git a/Fabric/Doc/command.sh b/Fabric/Doc/command.sh
new file mode 100755
index 0000000..3432392
--- /dev/null
+++ b/Fabric/Doc/command.sh
@@ -0,0 +1,18 @@
+
+# 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.
+
+
+#sudo ./oft --verbose --default-timeout=6 -i 1@eth1 -i 2@eth2 -i 3@eth3 --disable-ipv6 --switch-ip=192.168.2.2 --host=192.168.2.4 --of-version=1.3 --port=6633 --test-dir=accton --log-dir=log-dir
+sudo ./oft --verbose --default-timeout=6 -i 1@eth1 -i 2@eth2 -i 3@eth3 --disable-ipv6 --switch-ip=192.168.2.197 --host=192.168.2.4 --of-version=1.3 --port=6633 --test-dir=acctonUseDpctl --log-dir=log-dir phase1
\ No newline at end of file
diff --git a/Fabric/Doc/docs/Detailed_Testing_Methodology.txt b/Fabric/Doc/docs/Detailed_Testing_Methodology.txt
new file mode 100644
index 0000000..34922cc
--- /dev/null
+++ b/Fabric/Doc/docs/Detailed_Testing_Methodology.txt
@@ -0,0 +1,1822 @@
+						***********  Conformance Test-suite   ****************
+						OF-Switch-1.0.0-TestCases detailed testing methodology
+
+
+
+
+
+****     Openflow protocol messages     ****
+
+
+
+1. Features Request
+
+Test Description: Check features request is implemented
+
+Test mode: Automated
+Test Title: FeaturesRequest
+Ports: I (Control Plane)
+Initial State: Default (Clear switch state), Connection Setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Send OFPT_FEATURES_REQUEST from controller.
+b) Verify OFPT_FEATURES_REPLY is received without errors
+
+
+
+2. Configuration request
+
+Test Description: Check basic get configuration request is implemented
+
+Test mode: Automated
+Test Title: ConfigurationRequest
+Ports: I (Control Plane)
+Initial State: Default (Clear switch state), Connection Setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send OFPT_GET_CONFIG_REQUEST
+b) Verify OFPT_GET_CONFIG_REPLY is received without errors.
+
+
+
+3. Modify State (ADD)
+
+Test Description: Check basic Flow ADD request is implemented
+
+Test mode: Automated
+Test Title: ModifyStateAdd
+Ports: 3 (1 Control Plane 2 dataplane)
+Initial State: Default (Clear switch state), Connection Setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send OFPT_FLOW_MOD, command = OFPFC_ADD 
+b) Send ofp_table_stats request 
+c) Verify that active_count=1 in the reply
+
+
+
+
+4. Modify State (DELETE)
+
+Test Description: Check basic Flow Delete request is implemented
+
+Test mode: Automated
+Test Title: ModifyStateDelete
+Ports: 3 (1 Control Plane 2 dataplane)
+Initial State: Default (Clear switch state), Connection Setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send OFPT_FLOW_MOD, command = OFPFC_ADD 
+b) Send ofp_table_stats request
+c) Verify that active_count=1 in the reply
+d) Send OFPT_FLOW_MOD, command = OFPFC_DELETE
+e) Send ofp_table_stats request
+f)  Verify active _count=0 in the reply
+
+
+
+5. Modify State (MODIFY)
+
+Test Description: Check basic Flow Modify request is implemented
+
+Test mode: Automated
+Test Title: ModifyStateModify
+Ports: 3 (1 Control Plane and 2 Dataplane)
+Initial State: Default (Clear switch state), Connection Setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send  OFPT_FLOW_MOD , command = OFPFC_ADD, action A
+b) Send ofp_table_stats request, Verify  active_count=1
+c) Send OFPT_FLOW_MOD , command = OFPFC_MODIFY, action A’
+d) Send Test Packet  matching the flow
+e) Verify packet implements action A’
+
+
+
+6. Read State
+
+Test Description: Check basic Read State is implemented
+
+Test mode: Automated
+Test Title: ReadState
+Ports: 3 (1 Control Plane, 2 dataplane)
+Initial State: Default (Clear switch state), Connection Setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send  OFPT_FLOW_MOD, command = OFPFC_ADD
+b) Create a OFPC_FLOW_STATS message and send it
+c) Verify switch replies without errors
+
+
+
+7. Send packet
+
+Test Description: Check basic Send-Packet is implemented. 
+		  Send-Packet: These are used by the controller to send packets out of a specified port on the switch.
+
+Test mode: Automated
+Test Title:  SendPacket
+Ports: 5 (1 Control Plane, 4 Dataplane) 
+Initial State: Default (Clear switch state), Connection Setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send OFPT_PACKET_OUT out message from controller to switch for every dataplane port.
+b) Verify the packet appears on the each dataplane port
+c) Verify sent packet matches the received packet
+
+
+
+8. Barrier Request 
+
+Test Description: This test checks that a basic barrier request does not generate an error.
+
+Test mode: Automated
+Test Title: BarrierRequestReply
+Ports: I (Control Plane)
+Initial State: Default (Clear switch state), Connection Setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send OFPT_BARRIER_REQUEST
+c) Verify OFPT_BARRIER_REPLY is received on the control plane.
+
+
+
+9. Packet In
+
+Test Description: Check packet_in is implemented. This test just checks that non matched dataplane packets 
+		  generate a packet_in
+
+Test mode: Automated
+Test Title: PacketIn
+Ports: 2 (1 Control Plane and 1 Dataplane)
+Initial State: Default (Clear switch state), Connection Setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send a packet to dataplane port , without inserting a flow entry
+b) Verify a OFPT_PACKET_IN is generated on the control plane
+
+
+
+10. Hello
+
+Test Description: This test checks for basic Hello message generation with correct version field.
+
+Test mode: Automated
+Test Title:  Hello
+Ports: 1 (Control Plane)
+Initial State: Default (Clear switch state), Connection Setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send  OFPT_HELLO from controller to switch
+b) Verify switch also sends OFPT_HELLO message in response 
+c) Verify version field in the hello message is set to Openflow version 1.0.0
+
+
+
+11. Echo
+
+Test Description: This test checks for basic Echo Reply message generation with correct version field with 
+		  same transaction id.
+
+Test mode: Automated
+Test Title:  EchoWithoutBody
+Ports: 1 (Control Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send OFPT_ECHO_REQUEST from the controller side.
+b) Verify switch responds back with OFPT_ECHO_REPLY with same xid.
+c) Verify Openflow version in header is set to Openflow version 1.0.0.
+
+
+
+
+
+****     Detailed controller to switch messages     ****
+
+
+
+1. Overlap checking
+
+Test Description: Verify that if overlap check flag is set in the flow entry and an overlapping flow is 
+		  inserted then an error is generated and switch refuses flow entry
+
+Test mode: Automated
+Test Title:  OverlapChecking
+Ports: 3 (1 Control Plane 2 dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test-Notes:
+
+a) Generate Flow F1--> Wildcard All 
+b) Send ofp_table_stats request , verify active_count=1
+c) Generate overlapping flow F2 --> Wildcard All Except Ingress Port ( with flag OFPFF_CHECK_OVERLAP set)
+d) Verify that switch generates OFPT_ERROR msg.  
+   Type: OFPET_FLOW_MOD_FAILED code : OFPFMFC_OVERLAP 
+
+
+
+2. No overlap checking
+
+Test Description: Verify that without overlap check flag set, overlapping flows can be created.
+
+Test mode: Automated
+Test Title:  NoOverlapchecking
+Ports: 3 (1 Control Plane, 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Generate Flow F1--> Wildcard All.
+b) Send ofp_table_stats request , verify active_count=1
+e) Generate overlapping flow F2 --> Wildcard All Except Ingress Port ( without flag OFPFF_CHECK_OVERLAP set)
+c) Send a ofp_table_stats request, verify active_count=2
+
+
+
+3. Identical flows 
+
+Test Description: Verify that adding two identical flows overwrites the existing one and clears counters
+
+Test mode: Automated
+Test Title:  IdenticalFlows
+Ports: 3 (1 Control Plane), (2 dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Generate Flow F1.
+b) Send ofp_table_stats request , verify active_count=1
+b) Increment counters (packet_count, byte_count) by sending a packet matching flow F1.
+C) Send ofp_flow_stats request. Verify flow counters: byte_count and packet_count 
+c) Create identical flow F2
+d) Send a ofp_table_stats request, verify active_count=1
+e) Send ofp_flow_stats request. Verify flow counters: byte_count and packet_count are reset
+
+
+
+4. No table to add (Written in oftest—Need to add to conformance Test-Suites)
+
+
+
+5. Never valid port (TBD)
+
+
+
+
+6. Currently not existing port Version A and B (TBD)
+
+
+
+
+7. Emergency flow with timeout values 
+
+Test Description: Timeout values are not allowed for emergency flows
+
+Test Title: EmerFlowTimeout
+Test mode: Automated
+Ports: 3 (1 control plane, 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup 
+
+
+Test Notes:
+
+a)  Generate a flow F with OFPFF_EMERG set in flag and timeout values assigned.
+b)  Verify switch generates an OFPT_ERROR msg, Type: OFPET_FLOW_MOD_FAILED, Code OFPFMFC_BAD_EMERG_TIMEOUT
+
+
+
+8. Missing modify adds
+
+Test Description: If a modify does not match an existing flow, the flow gets added.
+
+Title: MissingModifyAdd
+Test mode: Automated
+Ports:3 (1 control plane,2 Data Plane)
+Initial State: Connection setup, Clear Switch State
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Generate a flow-mod , command OFPC_MODIFY (Note: There should be no flows matching this flow_mod modify command)
+b) Send a ofp_table_stats request, verify active_count=1
+
+
+
+
+9. Modify changes action, preserves counters
+
+Test Description: A modified flow preserves counters
+
+Title: ModifyAction
+Test mode: Automated
+Ports: 4(1 control plane, 3 Dataplane)
+Initial State: Connection setup, Clear Switch State
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Create a flow_mod F-1 with command OFPC_ADD, action A
+b) Send a test Packet matching the flow
+c) Send an ofp_flow_stats request, verify byte_count and packet_count
+e) Create flow_mod with command OFPC_MODIFY ,action A’ and modify action of flow F-1
+f) Send a ofp_flow_stats request, verify flow counters are preserved
+g) Send test packet, verify it implements action A’
+
+
+
+10. Strict Modify changes action, preserves counters
+
+Test Description: Strict Modify Flow also changes action preserves counters
+
+Title: StrictModifyAction
+Test mode: Automated
+Ports: 4(1 control plane, 3 Dataplane)
+Initial State: Connection setup, Clear Switch State
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Create two overlapping flows: F --> Match on all, except one wildcarded (src address). Action A. Priority=100 
+   F’ --> Match on ingress_port = port [0], wildcarded rest. Action A. Priority=10
+b) Send a ofp_table_stats request, verify active_count=2
+c) Send Packet (it would have matched both the flows, since they are overlapping flows but it would match Flow-F1 as it has higher priority.)
+d) Send ofp_flow_stats request for Flow-1 and verify counters packet_count and byte_count 
+e) Create flow_mod ,command OFPC_STRICT_MODIFY,match on all except src address ,priority 100 action A’
+f) Send test packet , verify action is modified
+g) Send ofp_flow_stats request, verify counters are preserved.
+
+
+
+
+11. Delete non existing flow 
+
+Test Description: Request deletion of non-existing flow
+
+Title: DeleteNonexistingFlow
+Test mode: Automated
+Ports: 1(1 control plane)
+Initial State: Connection setup, Clear Switch State
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Issue a delete command, with no flows inserted
+b) Make sure no error is generated on the control plane
+
+
+
+12. Delete flows with and without removed message
+
+Test Description: Check deletion of flows happens and generates messages as configured. i.e. if ‘Send Flow removed message’Flag 
+	          is set in the flow entry, the flow deletion of that respective flow should generate the flow removed message, 
+		  vice versa also exists 
+
+Test Title: SendFlowRem
+Test mode: Automated
+Ports: 3 (1 control plane, 2 Dataplane)
+Initial State: Connection setup, Default (clear switch state)
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Generate a flow F without OFPFF_SEND_FLOW_REM flag set
+b) Issue a delete command OFPFC_DELETE
+c) Verify that OFPT_FLOW_REMOVED message is not generated.
+c) Generate a flow F’ with OFPFF_SEND_FLOW_REM flag set
+d) Issue a delete command OFPFC_DELETE
+e) Verify that OFPT_FLOW_REMOVED message is generated
+
+
+
+13. Delete emergency flow 
+
+Test Description: Delete emergency flow and verify no message is generated.An emergency flow deletion will not generate 
+		  flow-removed messages even if ‘Send Flow removed message’ flag was set during the emergency flow entry.
+		  
+
+Title: DeleteEmerFlow
+Test mode: Automated
+Ports: 3 (1 control plane, 2 Dataplane)
+Initial State: Connection setup, Clear Switch State (default) 
+
+
+Test-Notes:
+
+a) Insert a flow with OFPFF_EMERG flag set.
+b) Delete the added flow with OFPFF_SEND_FLOW_REM flag set
+c) Test successful if no flow removed message is generated.
+
+
+
+14. Delete and verify strict and non-strict 
+
+Test Description: Delete and verify strict and non-strict behaviors
+
+This test compares the behavior of delete strict and non-strict.
+Title: StrictVsNonstrict
+Test mode: Automated
+Ports: 3 (1 control plane, 2 dataplane)
+Initial State: Connection setup, Clear Switch State
+
+
+Test-Notes:
+
+a) Insert Flow F with an exact match. 
+b) Issue Non-strict Delete command, verify F gets deleted. 
+c) Insert F with an exact Match 
+d) Issue Strict Delete Command, verify F gets deleted.
+e) Insert Flow T with match on all, except one wildcarded (say src address).  
+f) Insert another flow T' with match on ingress_port, wildcarded rest.  
+g) Issue Non-strict Delete ( match on ingress_port). Verify T+T' gets deleted. 
+h) Insert T and T' again. Issue Strict Delete (match on ingress port), verify only T' gets deleted
+i) Insert T, add Priority P (say 100) 
+j) Insert T' add priority (200). 
+k) Insert T' again add priority 300 --> T”
+l) Issue Non-Strict Delete (match on ingress port). Verify T+T’+T’’ gets deleted. 
+m) Insert T, T’, T’’ again, Issue Strict Delete (match on ingress_port) with priority = 200. Verify only T’ gets deleted
+
+
+
+15. Delete flows with constraint out_port
+
+Test Description: Delete flows filtered by action output.DELETE and DELETE STRICT commands can be optionally filtered by output port.
+		  If the out_port field contains a value other than OFPP_NONE, it introduces a constraint when matching. 
+		  This constraint is that the rule must contain an output action directed at that port.
+
+Title: Outport1
+Test mode: Automated
+Ports: 3 (1 control plane, 2 Dataplanes)
+Initial State: Connection setup, Clear Switch State
+Test-Field: Mandatory
+
+
+Test-Notes:
+
+a) Insert a flow F  with output action = port x 
+b) Send a delete command matching flow F ,but  out_port =port y
+c) Send a table_stats request , verify no flow gets deleted i.e. active_count=1
+d) Send a delete command matching flow F ,outport = port x
+e) Send a table_stats request, verify flow F gets deleted.
+
+
+
+16. Add, modify flows with constraint output
+
+Test Description: Add, modify flows with outport set. This field is ignored by ADD, MODIFY, and MODIFY STRICT messages.
+
+Title: Outport2
+Test mode: Automated
+Ports: 4 (1 control plane, 3 Data planes)
+Initial State: Connection setup, Clear Switch State
+Test-Field: Mandatory
+
+Test-Notes:
+
+a) Insert a flow F with action A (output --> port x) , but out_port field in the flow mod set as port y
+b) Send Table_Stats_Request, Verify Flow gets inserted. ( Flow add ignores out_port field)
+c) Modify the action in flow F , action A’ ( output -->port z ), but out_port field in the flow mod set as port y
+d) Send test packet matching the flow F 
+e) Verify packet implements action A’ (flow modify ignores out_port field)
+
+
+
+17. Verify that idle timeout is implemented
+
+Test Description: Verify that idle timeout is implemented
+
+Title: IdleTimeout
+Test mode: Automated
+Ports: 3 (1 control plane, 2 Dataplanes)
+Initial State: Connection setup, Clear Switch State
+Test-Field: Mandatory
+
+
+Test-Notes:
+
+a) Add a flow with idle timeout set and with OFPP_SEND_FLOW_REM bit set
+b) Verify flow removed message is received.
+c) Verify flow removed reason was idle_timeout
+d) Verify the duration_sec field is 1 sec 
+
+
+
+18. Verify that hard timeout is implemented
+
+Test Description: Verify that hard timeout is implemented
+
+Title: HardTimeout
+Test mode: Automated
+Ports: 3 (1 control plane, 2 Dataplanes)
+Initial State: Connection setup, Clear Switch State 
+Test-Field: Mandatory
+
+
+Test-Notes:
+
+a) Add a flow with hard timeout =1 set and with OFPP_SEND_FLOW_REM bit set
+b) Verify flow removed message is received.
+c) Verify flow removed reason was hard_timeout
+d) Verify the duration_sec field is 1 sec 
+
+
+
+19. Verify that messages are generated as expected
+
+Test Description: Verify that Flow removed messages are generated as expected
+	          /* Since “flow removed messages being generated when flag is set” is already tested in the above tests 
+                  So here, we test the vice-versa condition.*/
+
+Title: FlowTimeout
+Test mode: Automated
+Ports: 3 (1control plane, 1dataplane)
+Initial State: Connection setup, Clear Switch State 
+Test-Field: Mandatory
+
+
+Test-Notes:
+
+a)  Generate and install a flow with idle_timeout = 1 set no OFPFF_SEND_FLOW_REM flag set.
+b)  Verify no flow removed message is received.
+c)  Send table_stats_request message and verify active_count=0 
+
+
+
+
+
+***   Actions   ***
+
+
+
+1. No Action drops packet 
+
+Test Description: If no forward actions are present, the packet is dropped. 
+		
+Required Action: Drop. 
+A flow-entry with no specified action indicates that all matching packets should be dropped. 
+Test mode: Automated
+Test Title:  NoAction
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send Flow mod message without any action specified
+b) Send N packets matching the flow 
+c) Verify packets are not received on any of the dataplane ports 
+d) Verify packets are not even sent to the controller
+
+
+
+2.  Get supported actions from switch
+
+Test Description: Get the supported actions from switch and make sanity checks.
+		  /*When connecting to the controller, a switch indicate which of the “Optional Actions” it supports*/
+
+Test mode: Automated
+Test Title:  Announcement
+Ports: 1 (Control Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+       
+
+Test Notes: 
+
+a) Send features_request .
+b) Verify response is OFPT_FEATURES_REPLY
+c) Verify reply has supported action list specified
+
+
+
+3. Forward All
+
+Test Description: Packet is sent to all dataplane ports except ingress port when output action.port = OFPP_ALL
+
+Test mode: Automated
+Test Title:  ForwardAll
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+       
+Test Notes: 
+
+a) Install a flow with output action.port = OFPP_ALL.
+b) Verify packets are forwarded to all ports except ingress port.
+
+
+
+4. Forward Controller 
+
+Test Description: Packet is sent to controller output.port = OFPP_CONTROLLER
+
+Test mode: Automated
+Test Title:  ForwardController
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+       
+Test Notes: 
+
+a) Insert a flow with action output port = OFPP_CONTROLLER
+b) Send packets matching the flow
+c) Verify packet received on the control plane as a packet_in message
+
+
+
+5. Forward Local (TBD – Verification of packet being received at local networking stack)
+
+Test Description: Packet is sent to switch’s local networking stack if output.port = OFPP_LOCAL
+
+Test mode: Automated
+Test Title:  ForwardLocal
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+       
+Test Notes: 
+
+a) Insert a flow with action output port = OFPP_LOCAL
+b) Send packets matching the flow
+c) Verify packet received in the switch’s local networking stack.
+
+
+
+6. Forward Table
+
+Test Description: Perform actions in flow table. Only for packet-out messages.
+		  /*If the output action.port in the packetout message = OFP.TABLE, then the packet implements the action 
+		  specified in the matching flow of the FLOW-TABLE*/
+
+Test mode: Automated
+Test Title:  ForwardTable
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+Test Notes: 
+
+a) Insert a flow F with action output.port = egress_port
+b) Send a OFPT_PACKET_OUT message with out port=OFPP_TABLE matching flow F 
+c) Verify packet received on egress_port (i.e packetout message implemented the action specified in the matching flow of the Table)
+
+
+
+7. Forward In Port
+
+Test Description: Packet is sent to input port if output.port = OFPP_INPORT
+
+Test mode: Automated
+Test Title:  ForwardInport
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+Test Notes: 
+
+a) Insert a flow with action output port = OFPP_INPORT
+b) Send packets matching the flow
+c) Verify packet received on all dataplane ports except for input port
+
+
+
+8. Forward Flood
+
+Test Description:Flood the packet along the minimum spanning tree, not including the incoming interface. 
+		 Packet is sent all the dataplane ports except the input port if output.port = OFPP_FLOOD
+
+Test mode: Automated
+Test Title:  Forward_Flood
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+Test Notes: 
+
+a) Insert a flow with action output port = OFPP_FLOOD
+b) Send packets matching the flow
+c) Verify packet received on all dataplane ports except for input port
+
+
+
+9. Multiple Ports -- TBD
+
+
+
+
+10. Forward Enqueue --- TBD
+
+
+
+
+11. Set VLAN Id
+
+Test Description: Attach VLAN ID to untagged packet.
+                  If no VLAN is present, a new header is added with the specified VLAN ID and priority of zero.
+
+Test mode: Automated
+Test Title:  AddVlanId
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+       
+Test Notes: 
+
+a) Insert a flow with action = OFPAT_SET_VLAN_VID , vlan_vid = x 
+b) Send packet (length = 100 bytes) matching the flow
+b)   Verify packet received has vlan id added to it. (I.e length of packet with vid is 104 bytes, dl_vlan_enable = True, dl_vlan= x, dl_vlan_pcp=0)  
+   
+
+
+12. Modify VLAN Id
+
+Test Description: Modifies Vlan Tag for a tagged packet
+		  If a VLAN header already exists, the VLAN ID is replaced with the specified value
+
+Test mode: Automated
+Test Title:  ModifyVlanId
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+
+Test Notes: 
+a) Insert a flow with action = OFPAT_SET_VLAN_VID , vlan_vid = x 
+b)   Send packet (length = 100 bytes) matching the flow
+c)   Verify packet received has vlan id rewritten. (I.e length of 104 bytes, dl_vlan_enable = True, dl_vlan=x)  
+
+
+
+13. Add VLAN Priority to an untagged packet
+
+Test Description: Attach VLAN priority to an untagged packet.
+		  Since, no VLAN ID is present; a new header is added with the specified priority and a VLAN ID of zero.\
+
+Test mode: Automated
+Test Title:  VlanPrio1
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+       
+Test Notes: 
+
+a) Insert a flow with action = OFPAT_SET_VLAN_PCP , dl_vlan_pcp =x
+b) Send untagged packet matching the flow  
+c) Verify packet received has vlan priority added to it along with a vid value of zero added by default   (dl_vlan_enable , dl_vlan = 0 , dl_vlan_pcp =x )
+
+
+
+14. Rewrite existing VLAN priority
+
+Test Description: Modify VLAN priority for a tagged packet.
+
+Test mode: Automated
+Test Title:  VlanPrio2
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+       
+Test Notes: 
+
+a) Insert a flow with action = OFPAT_SET_VLAN_PCP , dl_vlan_pcp =new_vlan_pcp
+b) Send tagged packet matching the flow  (dl_vlan = old_vlan_id , dl_vlan_pcp = old_vlan_pcp)
+c) Verify packet received has vlan id added to it. (dl_vlan_enable , dl_vlan = 0 , dl_vlan_pcp = new_vlan_pcp)
+
+
+
+
+15. Modify L2 Src Address
+
+Test Description: Modify Ethernet Src Address of a packet
+
+Test mode: Automated
+Test Title:  ModifyL2Src
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+       
+Test Notes: 
+
+a) Insert a flow with action = OFPAT_SET_DL_SRC , dl_src =new_dl_src
+b) Send packet matching the flow  (dl_dst = old_dl_src )
+c) Verify packet received has src address rewritten. (dl_src= new_dl_src)
+
+
+
+16. Modify L2 Destination Address
+
+Test Description: Modify Ethernet Destination Address of a packet
+
+Test mode: Automated
+Test Title:  ModifyL2Dst
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+       
+Test Notes: 
+
+a) Insert a flow with action = OFPAT_SET_DL_DST , dl_dst =new_dl_dst
+b) Send packet matching the flow  (dl_dst = old_dl_src )
+c) Verify packet received has destination address rewritten. (dl_src= new_dl_src)
+
+
+
+17. Strip VLAN header – (In oftest,  need to add in conformance test-suite )
+
+
+
+18. Modify L3 Src Address
+
+Test Description: Modify Network Src Address of a packet
+
+Test mode: Automated
+Test Title:  ModifyL3Src
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+       
+Test Notes: 
+
+a) Insert a flow with action = OFPAT_SET_NW_SRC , nw_src =new_nw_src
+b) Send packet matching the flow  (nw_src = old_nw_src )
+c) Verify packet received has nw address rewritten. (nw_src= new_nw_src)
+
+
+
+19. Modify L3 Dst Address
+
+Test Description: Modify Network Dst Address of a packet
+
+Test mode: Automated
+Test Title:  ModifyL3Dst
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+       
+Test Notes: 
+
+a) Insert a flow with action = OFPAT_SET_NW_DST , nw_dst =new_nw_dst
+b) Send packet matching the flow  (nw_dst = old_nw_dst )
+c) Verify packet received has nw destination address rewritten. (nw_dst= new_nw_dst)
+
+
+
+20. Modify L4 Src Address
+
+Test Description: Modify TCP Source Port of a packet
+
+Test mode: Automated
+Test Title:  ModifyL4Src
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+       
+Test Notes: 
+
+a) Insert a flow with action = OFPAT_SET_TP_SRC , tcp_sport =new_tcp_sport
+b) Send packet matching the flow  (tcp_sport = old_tcp_sport )
+c) Verify packet received has tcp source port rewritten. (tcp_sport = new_tcp_sport)
+
+
+21. Modify L4 Dst Address
+
+Test Description: Modify TCP Destination Port of a packet
+
+Test mode: Automated
+Test Title:  ModifyL4Dst
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+       
+Test Notes: 
+
+a) Insert a flow with action = OFPAT_SET_TP_DST , tcp_dport =new_tcp_dport
+b) Send packet matching the flow  (tcp_dport = old_tcp_dport )
+c) Verify packet received has tcp destination port rewritten. (tcp_sport = new_tcp_sport)
+
+
+
+22. Modify TOS
+
+Test Description: Modify Network Type of service
+
+Test mode: Automated
+Test Title:  ModifyTos
+Ports: 3 (1 Control Plane 2 Dataplane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+       
+Test Notes: 
+
+a) Insert a flow with action = OFPAT_SET_NW_TOS, ip_tos =new_ip_tos
+b) Send packet matching the flow  (ip_tos= old_ip_tos)
+c) Verify packet received has tcp destination port rewritten. (ip_tos= new_ip_tos)
+
+
+
+23. Order Not possible  -- TBD
+
+
+
+
+24. Sequential execution  -- TBD 
+
+
+
+
+
+****     Counters     ****
+
+
+
+1. Received Packets per Flow
+
+
+Test Description: Verify that packet_count in the Flow_Stats reply increments in accordance with the packets in flow  
+
+Test mode: Automated
+Test Tile: PktPerFlow
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow , match = ingress_port
+b) Send N packet matching the flow  i.e packets should be sent on ingress_port
+c) Send flow_stats_request for the flow 
+d) Verify packet_count = N in the flow_stats_reply
+
+
+
+2. Received Bytes per Flow
+
+
+Test Description: Verify that byte_count in the Flow_Stats reply increments in accordance with the bytes in flow  
+
+Test mode: Automated
+Test Tile: BytPerFlow
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow , match = ingress_port
+b) Send N packet matching the flow  i.e packets should be sent on ingress_port
+c) Send flow_stats_request for the flow 
+d) Verify byte_count = N*(no. of bytes in one packet) in the flow_stats_reply
+
+
+
+3. Duration in sec per Flow
+
+
+Test Description: Verify that duration_sec in the Flow_Stats reply increments in accordance with the time that flow was alive in sec 
+
+Test mode: Automated
+Test Tile: DurationPerFlow
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a any flow 
+b) Send flow_stats_request for that flow periodically after n sec intervals upto timeout of y 
+c) Verify each flow_stats_reply has duration_sec field incrementing as n , 2n , 3n .. y 
+
+
+
+4. Duration in nsec per flow
+
+
+Test Description: Verify that duration_nsec in the flow_stats repl increments in accordance with the time flow has been alive in nanoseconds 
+beyond duration_sec.
+
+Test mode: Automated
+Test Tile: DurationPerFlow
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert any flow 
+b) Send flow_stats_request periodically after n sec intervals upto timeout of y 
+c) Verify each flow_stats_reply has duration_sec field incrementing as n , 2n , 3n .. y and read out duration_nsec field ( Verification of nsec field 
+is out of scope)
+
+
+
+5. Received packets per port
+
+
+Test Description: Verify that rx_packets in the Port_Stats reply increments in accordance with the packets recieved on that port
+
+Test mode: Automated
+Test Tile: RxPktPerPort
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match on ingress_port
+b) Send N packets on the ingress_port 
+c) Send port_stats request for port=ingress_port
+d) Verify port_stats_reply has rx_packet=N
+
+
+
+
+6. Transmitted packets per port
+
+
+Test Description: Verify that tx_packets in the Port_Stats reply increments in accordance with the packets transmitted from a port  
+
+Test mode: Automated
+Test Tile: TxPktPerPort
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match on ingress_port, action output = egress_port
+b) Send N packets on the ingress_port
+c) Send port_stats request for port=ingress_port
+d) Verify port_stats_reply had tx_packets=N   
+
+
+
+7. Received Bytes per port
+
+
+Test Description: Verify that rx_bytes in the Port_Stats reply increments in accordance with the bytes recieved on a port  
+
+Test mode: Automated
+Test Tile: RxBytPerPort
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match on ingress_port, action output = egress_port
+b) Send N packet matching the flow  
+c) Send port_stats request for port=ingress_port
+d) Verify port_stats_reply had rx_bytes=N*(no. of bytes in a packet) 
+
+
+
+8. Transmitted Bytes per port
+
+
+Test Description: Verify that tx_bytes in the Port_Stats reply increments in accordance with the bytes transmitted from a port  
+
+Test mode: Automated
+Test Tile: TxBytPerPort
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match on ingress_port, action output = egress_port
+b) Send N packet matching the flow  
+c) Send port_stats request for port=ingress_port
+d) Verify port_stats_reply had tx_bytes=N*(no. of bytes in a packet) 
+
+
+
+9. Recieve Drops per port (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that rx_dropped counters in the Port_Stats reply increments in accordance with the packets dropped by RX  
+
+Test mode: Automated
+Test Tile: RxDrops
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+Test Notes :
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has rx_dropped count
+
+
+
+
+
+10. Transmit Drops per port (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that tx_dropped counters in the Port_Stats reply increments in accordance with the packets dropped by TX
+
+Test mode: Automated
+Test Tile: TxDrops
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Manadatory
+
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has tx_dropped count
+
+
+
+
+11. Recieve Errors (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that rx_errors counters in the Port_Stats reply increments in accordance with number of recieved error  
+		  This is a super-set of more specific receive errors and should be greater than or equal to the sum of all
+                  rx_*_err values.
+
+Test mode: Automated
+Test Tile: RxErrors
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has rx_errors count
+
+
+
+12. Transmit Errors (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that tx_errors counters in the Port_Stats reply increments in accordance with number of trasmit errors  
+
+Test mode: Automated
+Test Tile: TxErrors
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has tx_errors count
+
+
+
+13. Recieve Frame Errors (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that rx_frm_err counters in the Port_Stats reply increments in accordance with the number of frame alignment errors
+Test mode: Automated
+Test Tile: RxFrameErr
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has rx_frame_err count 
+
+
+
+14. Recieve Overrun Errors (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that rx_over_err counters in the Port_Stats reply increments in accordance with the number of with RX overrun
+
+Test mode: Automated
+Test Tile: RxOErr
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has rx_over_err count 
+
+
+15. CRC Errors (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that rx_crc_err counters in the Port_Stats reply increments in accordance with the number of crc errors
+
+Test mode: Automated
+Test Tile: RxCrcErr
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Manadatory
+
+
+Test Notes: 
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has rx_crc_err count 
+
+
+
+16. Collisions (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that collisons counters in the Port_Stats reply increments in accordance with the collisions encountered by the switch
+
+Test mode: Automated
+Test Tile: Collisions
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has collisions count 
+
+
+
+17. Active Entries per Table
+
+
+Test Description: Verify that active_count in the table increments in accordance with the flows inserted in the table
+
+Test mode: Automated
+Test Tile: ActiveCount
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow 
+b) Send table_stats_request
+c) Verify active_count=1
+
+
+
+18. Packet Lookup per Table
+
+
+Test Description: Verify that lookup_count in the Table_Stats reply increments in accordance with the number of packets looked up in table
+
+Test mode: Automated
+Test Tile: LookupMatchedCount
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match on ingress_port
+b) Send N packets on ingress_port (matching the flow)
+c) Send N' packets on x port (Not matching the flow)
+d) Send table_stats_request 
+e) Verify lookup_count = N+N' 
+
+
+
+19. Packets matched per Table
+
+Test Description: Verify that matched_count in the Table_Stats reply increments in accordance with the number of packets matched with the table
+
+Test mode: Automated
+Test Tile: LookupMatchedCount
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match on ingress_port
+b) Send N packets on ingress_port (matching the flow)
+c) Send N' packets on x port (Not matching the flow)
+d) Send table_stats_request 
+e) Verify matched_count = N 
+
+
+
+
+20. Transmit Packets per Queue
+
+Test Description: Verify that tx_packets in the queue_stats reply increments in accordance with the number of transmitted packets
+
+Test mode: Automated
+Test Tile: TxPktPerQueue
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+
+Test Notes: 
+
+a) Send queue_stats request for ports=ofp.OFPP_ALL and queue_ids=ofp.OFPQ_ALL (i.e all ports and all queues)
+b) Send queue_stats request for egress_port[0] and queue_id[0] and note the tx_packets count in the reply
+c) Insert a flow entry with enqueue action , port = egress_port[0] queue_id= queue_id[0]
+d) Send packet matching the flow
+e) Send queue_stats request again, verify tx_packet count incremented 
+f) Repeat b , c , d , e for all the queue_ids configured for egress_port[0]
+h) Repeat b , c , d , e , f for all the egress_ports available
+
+
+
+
+21. Transmit Bytes per Queue
+
+Test Description: Verify that tx_bytes in the queue_stats reply increments in accordance with the number of transmitted bytes
+
+Test mode: Automated
+Test Tile: TxBytPerQueue
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+
+Test Notes: 
+
+a) Send queue_stats request for ports=ofp.OFPP_ALL and queue_ids=ofp.OFPQ_ALL (i.e all ports and all queues)
+b) Send queue_stats request for egress_port[0] and queue_id[0] and note the tx_bytes count in the reply
+c) Insert a flow entry with enqueue action , port = egress_port[0] queue_id= queue_id[0]
+d) Send packet matching the flow
+e) Send queue_stats request again, verify tx_byte count incremented 
+f) Repeat b , c , d , e for all the queue_ids configured for egress_port[0]
+h) Repeat b , c , d , e , f for all the egress_ports available
+
+
+
+22. Transmit Overrun Errors per queue (TBD ----> Verification of tx_error count being incremented correctly) 
+
+Test Description: Verify that tx_errors in the queue_stats reply increments in accordance with the number of packets dropped due to overrun.
+Test mode: Automated
+Test Tile: TxErrorPerQueue
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+Test Notes: 
+
+
+a) Send queue_stats request for port=egress_port and queue_ids=ofp.OFPQ_ALL
+B) send queue_stats request for egress_port and queue_id[0] (i.e first queue configured for egress_port)
+c) Verify reply has tx_errors count .
+d) Repear b , c for the all queue_ids of egress_port
+
+
+
+
+
+****     Flow matches     ****
+
+
+
+1. All Wildcard Match
+
+Test Description: Adding a Flow that matches all the possible fields
+
+Test mode: Automated
+Test Tile: AllWildcardMatch
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with wildcard = OFPFW_ALL (wildcard all fields), action output to egress_port
+b) Send packets with different header fields
+c) Verify all packets match the flow and implement the action specified.
+
+
+2. Single Header Field: Ingress Port
+
+Test Description: Match on Ingress Port and Wildcard rest 
+
+Test mode: Automated
+Test Tile: IngressPort
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match = in_port (say port x), action output to egress_port
+b) Send packet on port x 
+c) Verify packet was recieved on egress_port
+d) Send packet on port y
+e) Verify PacketIn event was triggered on control plane
+
+
+
+3. Single Header Field: Ethernet Src Address
+
+Test Description: Match on Ethernet Source Address and Wildcard rest 
+
+Test mode: Automated
+Test Tile: EthernetSrcAddress
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match = dl_src (say x) , action output to egress_port
+b) Send packet wth dl_src = x 
+c) Verify packet was recieved on egress_port
+d) Send packet with dl_src = y 
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+4. Single Header Field: Ethernet Dst Address
+
+Test Description: Match on Ethernet Destination Address and Wildcard rest 
+
+Test mode: Automated
+Test Tile: EthernetDstAddress
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match = dl_dst (say x) , action output to egress_port
+b) Send packet wth dl_dst = x  
+c) Verify packet was recieved on egress_port
+d) Send packet with dl_dst = y 
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+5. Single Header Field: Ethernet Type 
+
+Test Description: Match on Ehternet Type and Wildcard rest 
+
+Test mode: Automated
+Test Tile: EthernetType
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match = dl_type (say x) , action output to egress_port
+b) Send packet wth dl_type = x   
+c) Verify packet was recieved on egress_port
+d) Send packet with dl_type = y 
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+
+6. Single Header Field: Vlan Id
+
+Test Description: Match on Ingress Port and Wildcard rest 
+
+Test mode: Automated
+Test Tile: VlanId
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match = dl_vlan (say x) , action output to egress_port
+b) Send a tagged packet with (dl_vlan_enable=True,dl_vlan = x)  
+c) Verify packet was recieved on egress_port
+d) Send another tagged packet with (dl_vlan_enable=True,dl_vlan = y )
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+
+7. Single Header Field: Vlan PCP
+
+Test Description: Match on Vlan ID Priority 
+
+Test mode: Automated
+Test Tile: VlanPcp
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match = dl_vlan_pcp (say x) , action output to egress_port
+b) Send a tagged packet with (dl_vlan_enable=True, dl_vlan = * , dl_vlan_pcp = x)  
+c) Verify packet was recieved on egress_port
+b) Send a tagged packet with (dl_vlan_enable=True, dl_vlan = * , dl_vlan_pcp = y)  
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+
+
+8. Single Header Field: IP Src Address -------- > (TBD)
+
+Test Description: Match on IP Src Address and Wildcard rest 
+
+Test mode: Automated
+Test Tile: IPSrcAddress
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+
+
+9. Single Header Field: IP Dst Address -----------> (TBD)
+
+Test Description: Match on IP Dst Address and Wildcard rest 
+
+Test mode: Automated
+Test Tile: IPDstAddress
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+
+
+
+10. Single Header Field: IP protocol---------------> (TBD)
+
+Test Description: Match on IP Protocol and Wildcard rest 
+
+Test mode: Automated
+Test Tile: IPprotocol
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+
+
+
+
+11. Single Header Field: IP Tos bits
+
+Test Description: Match on IP Tos bits and Wildcard rest 
+
+Test mode: Automated
+Test Tile: IpTos
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match = nw_tos (say x) , action output to egress_port
+b) Send a tcp packet with (nw_tos=x)  
+c) Verify packet was recieved on egress_port
+b) Send a tcp packet with (nw_tos = y)
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+12. Single Header Field: Transport Source Port
+
+Test Description: Match on Transport Src Port and Wildcard rest 
+
+Test mode: Automated
+Test Tile: TcpSrcPort
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match = tp_src (say x) , action output to egress_port
+b) Send a tcp packet with (tp_src=x)  
+c) Verify packet was recieved on egress_port
+b) Send a tcp packet with tp_src= y)
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+13. Single Header Field: Transport Destination Port
+
+Test Description: Match on Transport Dst Port and Wildcard rest 
+
+Test mode: Automated
+Test Tile: TcpDstPort
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match = tp_dst (say x) , action output to egress_port
+b) Send a tcp packet with (tp_dst=x)  
+c) Verify packet was recieved on egress_port
+b) Send a tcp packet with tp_dst = y)
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+
+14. Multiple Header Fields: L2
+
+
+Test Description: Match on Ethernet Type, Ethernet Source Address, Ethernet Destination Address and Wildcard rest 
+
+Test mode: Automated
+Test Tile: MultipleHeaderFieldL2
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match = dl_type (say x), dl_src (say y ), dl_dst (say z), action output to egress_port
+b) Send a eth packet with dl_type (say x), dl_src (say y ), dl_dst (say z)
+c) Verify packet was recieved on egress_port
+b) Send a eth packet with dl_type (say w), dl_src (say v ), dl_dst (say f)
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+15. Multiple Header Fields: L3 ------> TBD
+
+
+
+
+16. Multiple Header Fields: L4
+
+Test Description: Match on Tcp Source Port, Tcp Destination Port
+
+Test mode: Automated
+Test Tile: MultipleHeaderFieldL4
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with match = tp_src (say x), tp_dst (say y )
+b) Send a tcp packet with tp_src (say x), tp_dst (say y )	
+c) Verify packet was recieved on egress_port
+b) Send a eth packet with tcp_src (say w), tcp_dst (say v )
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+17. All Header Fields: Exact Match flows
+
+Test Description: Verify exact flow matches are possible 
+
+Test mode: Automated
+Test Tile: ExactMatch
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert a flow with exact match, action output to egress_port
+b) Send packet matching the flow  
+c) Verify packet received on egress_port
+d) Send a non-matching packet
+e) Verify PacketIn event gets triggered
+
+
+
+18. Exact Match Highest Priority
+
+Test Description: An exact match flow entry has a highest priority compared to other flow entries 
+
+Test mode: Automated
+Test Tile: ExactMatchHigh
+POrts: 4 (1 Control Plane 3 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert two overlapping flows:
+	Exact Match (prio = p )   action egress_port
+	Wildacrd All (prio = p+ ) action egress_port2
+b) Send packet matching the flows
+c) Verify packet received on egress_port 
+
+
+
+
+19. Wildcard Match Highest Priority
+
+Test Description: If Wildcard flow entries have priority associated with them.
+		  Higher priority Wildcard flow overrides the lower priroty Wildcard flow  
+
+Test mode: Automated
+Test Tile: WildcardMatchHigh
+POrts: 4 (1 Control Plane 3 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes: 
+
+a) Insert two wildcarded flows :
+	Wildcard All Except ingress (prio = p ) , action = egress_port
+	Wildcard All (prio = p+ ) ,action = egress_port2
+b) Send packet matching the flows  
+c) Verify packet is recieved on egress_port2
+
+
+
+20. Fragment TCP Segments ------> TBD 
+
+Test Description: Create flow matching on tcp port number. Verify that fragmented packets always match that flow rule.
+
+Test mode: Automated
+Test Tile: FragTcpSeg
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
diff --git a/Fabric/Doc/docs/Doxyfile b/Fabric/Doc/docs/Doxyfile
new file mode 100644
index 0000000..85cfc63
--- /dev/null
+++ b/Fabric/Doc/docs/Doxyfile
@@ -0,0 +1,1417 @@
+# Doxyfile 1.5.6
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = 
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = 
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, 
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), 
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, 
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, 
+# and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = YES
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen to replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = "../src/python/oftest"  "../tests"
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS          = "*.py"
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = "python /usr/bin/doxypy.py"
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to FRAME, a side panel will be generated
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature. Other possible values 
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
+# and Class Hiererachy pages using a tree view instead of an ordered list;
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
+# disables this behavior completely. For backwards compatibility with previous
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
+# respectively.
+
+GENERATE_TREEVIEW      = NONE
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# By default doxygen will write a font called FreeSans.ttf to the output 
+# directory and reference it in all dot files that doxygen generates. This 
+# font does not include all possible unicode characters however, so when you need 
+# these (or just want a differently looking font) you can specify the font name 
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font, 
+# which can be done by putting it in a standard location or by setting the 
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 
+# containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# By default doxygen will tell dot to use the output directory to look for the 
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a 
+# different font using DOT_FONTNAME you can set the path where dot 
+# can find it using this tag.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is enabled by default, which results in a transparent 
+# background. Warning: Depending on the platform used, enabling this option 
+# may lead to badly anti-aliased labels on the edges of a graph (i.e. they 
+# become hard to read).
+
+DOT_TRANSPARENT        = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/Fabric/Doc/docs/flow_query_test_plan.txt b/Fabric/Doc/docs/flow_query_test_plan.txt
new file mode 100644
index 0000000..22742dc
--- /dev/null
+++ b/Fabric/Doc/docs/flow_query_test_plan.txt
@@ -0,0 +1,378 @@
+
+
+DRAFT TEST PLAN FOR TESTING TOP-HALF OF OpenFlow 1.0 SWITCH
+
+Draft 2 - 23 Apr 2012
+
+
+
+1.  GENERAL
+===========
+
+1.1  Test particular implementation, not OpenFlow protocol
+
+This test plan is intended to test the function of those features of an OF
+agent implementation that would be particular to a given switch,
+i.e. semantics of various OF operations are correctly implemented on a given
+switch.
+It is NOT intended to test:
+- syntactic featues, such as badly formed OF protocol messages, etc., nor
+- semantic features that would be common to all implementations, e.g.
+  qualifying on a VLAN id > 4095, an action to set VLAN PCP to a value > 7,
+  etc.
+
+
+2.  FLOW ADD
+============
+
+2.5  FLOW ADD 5
+---------------
+
+OVERVIEW
+- Add flows to switch, read back and verify flow configurations
+
+PURPOSE
+- Test acceptance of flow adds
+- Test ability of switch to process additions to flow table in random
+  priority order
+- Test correctness of flow configuration responses
+
+INPUTS
+- NUM_FLOWS: number of flows to define; 0 => maximum number of flows, as
+  determined from switch capabilities
+
+PROCESS
+1. Delete all flows from switch
+2. Generate NUM_FLOWS distinct flow configurations
+3. Send NUM_FLOWS flow adds to switch, for flows generated in step 2 above
+   - Flow mods with OFPFF_SEND_FLOW_REM = 0 (do not send remove message) and
+     OFPFF_CHECK_OVERLAP = 0 (do not check for overlap)
+4. Verify that no OFPT_ERROR responses were generated by switch
+5. Retrieve flow stats from switch
+6. Compare flow configurations returned by switch
+7. Test PASSED iff all flows sent to switch in step 3 above are returned in
+   step 5 above; else test FAILED
+
+NOTES
+- Will use randomized flow configuration, in an attempt to cover combinations
+  of qualifier wildcarding, qualifier values, actions and action parameters
+
+
+2.5.1  FLOW ADD 5.1
+-------------------
+
+OVERVIEW
+- Verify flow canonicalization
+
+PURPOSE
+- Test that switch properly canonicalizes a given flow definition
+  (canonicalization is defined as wildcarding out qualifiers when antecedent
+  qualifiers are not set correctly, e.g. nw_tos cannot be specified, and hence
+  must be wildcarded, if dl_type is not specified to be 0x0800 (IP))
+
+INPUTS
+None
+
+PROCESS
+1. Delete all flows from switch
+2. Generate 1 flow definition, which is different from its canonicalization
+3. Send flow to switch
+4. Retrieve flow from switch
+5. Compare returned flow to canonical form of defined flow
+7. Test PASSED iff flow received in step 4 above is identical to canonical
+   form of flow defined in step 3 above
+
+
+2.6  FLOW ADD 6
+---------------
+
+OVERVIEW
+- Test flow table capacity
+
+PURPOSE
+- Test switch can accept as many flow definitions as it claims
+- Test generation of OFPET_FLOW_MOD_FAILED/OFPFMFC_ALL_TABLES_FULL
+- Test that attempting to create flows beyond capacity does not corrupt flow
+  table
+
+INPUTS
+None
+
+PROCESS
+1. Delete all flows from switch
+2. Send OFPT_FEATURES_REQUEST to determine switch features
+3. For each table reported by step 2 above, send OFPT_STATS_REQUEST/
+   OFPST_TABLE to determine table features
+4. Generate (N + 1) distinct flow configurations, where N is the flow capacity
+   reported by the switch in steps 2 and 3 above
+   - Flow wildcarding must obey supported wildcards, for each table
+5. Send (N + 1) flow adds to switch, for flows generated in step 4 above
+   - Flow mods with OFPFF_SEND_FLOW_REM = 0 (do not send remove message) and
+     OFPFF_CHECK_OVERLAP = 0 (do not check for overlap)
+6. Verify that OFPET_FLOW_MOD_FAILED/OFPFMFC_ALL_TABLES_FULL error response
+   was generated by switch, for last flow mod sent
+7. Retrieve flow stats from switch
+8. Compare flow configurations returned by switch
+9. Test PASSED iff:
+   - error message received, for correct flow
+   - last flow definition sent to switch is not in flow table
+   else test FAILED
+
+
+2.7  FLOW ADD 7
+---------------
+
+OVERVIEW
+- Test flow redefinition
+
+PURPOSE
+- Verify that successive flow adds with same priority and match criteria
+  overwrite in flow table
+
+INPUTS
+None
+
+PROCESS
+1. Delete all flows from switch
+2. Generate flow definition F1
+3. Generate flow definition F2, with same key (priority and match) as F1,
+   but with different actions
+4. Send flow adds for F1 and F2 to switch
+   - Flow mods with OFPFF_SEND_FLOW_REM = 0 (do not send remove message) and
+     OFPFF_CHECK_OVERLAP = 0 (do not check for overlap)
+5. Retrieve flow stats from switch
+6. Compare flow configurations returned by switch
+7. Test PASSED iff 1 flow returned by switch, matching configuration of F2,
+   and with counters equal to 0; else test FAILED
+
+
+2.8  FLOW ADD 8
+---------------
+
+OVERVIEW
+- Add overlapping flows to switch, verify that overlapping flows are rejected
+
+PURPOSE
+- Test detection of overlapping flows by switch
+- Test generation of OFPET_FLOW_MOD_FAILED/OFPFMFC_OVERLAP messages
+- Test rejection of overlapping flows
+- Test defining overlapping flows does not corrupt flow table
+
+INPUTS
+None
+
+PROCESS
+1. Delete all flows from switch
+2. Generate flow definition F1
+3. Generate flow definition F2, with key overlapping F1, by wildcarding a
+   qualifier specified in F1
+4. Send flow adds to switch, for flows generated in steps 2 and 3 above
+   - Flow mods with OFPFF_SEND_FLOW_REM = 0 (do not send remove message) and
+     OFPFF_CHECK_OVERLAP = 1 (check for overlap)
+4. Verify that OFPET_FLOW_MOD_FAILED/OFPFMFC_OVERLAP error response was
+   generated by switch
+5. Retrieve flow stats from switch
+6. Compare flow configurations returned by switch
+7. Test PASSED iff:
+   - error message received, for overlapping flow
+   - overlapping flow is not in flow table
+   else test FAILED
+
+
+3.  FLOW MODIFY
+===============
+
+3.1  FLOW MODIFY 1
+------------------
+
+OVERVIEW
+- Strict modify of single existing flow
+
+PURPOSE
+- Verify that strict flow modify operates only on specified flow
+- Verify that flow is correctly modified
+
+INPUTS
+- NUM_FLOWS: number of flows to define; 0 => maximum number of flows,
+  as determined from switch capabilities
+
+PROCESS
+1. Delete all flows from switch
+2. Generate NUM_FLOWS distinct flow configurations
+3. Send NUM_FLOWS flow adds to switch, for flows generated in step 2 above
+   - Flow mods with OFPFF_SEND_FLOW_REM = 0 (do not send remove message) and 
+     OFPFF_CHECK_OVERLAP = 0 (do not check for overlap)
+4. Pick 1 defined flow F at random
+5. Generate new action list for F
+6. Send flow modify for F to switch
+4. Verify that no OFPT_ERROR responses were generated by switch
+5. Retrieve flow stats from switch
+6. Compare flow configurations returned by switch
+7. Test PASSED iff all flows sent to switch in step 3 and 6 above are
+   returned in step 5 above; else test FAILED
+
+
+3.2  FLOW MODIFY 2
+------------------
+
+OVERVIEW
+- Loose modify of existing flows
+
+PURPOSE
+- Verify that loose flow modify operates only on matching flows
+- Verify that matching flows are correctly modified
+
+INPUTS
+- NUM_FLOWS: number of flows to define; 0 => maximum number of flows, as
+  determined from switch capabilities
+
+PROCESS
+1. Delete all flows from switch
+2. Generate NUM_FLOWS distinct flow configurations
+3. Send NUM_FLOWS flow adds to switch, for flows generated in step 2 above
+   - Flow mods with OFPFF_SEND_FLOW_REM = 0 (do not send remove message) and
+     OFPFF_CHECK_OVERLAP = 0 (do not check for overlap)
+4. Pick 1 defined flow F at random
+5. Wildcard out 1 qualifier in match of F, creating F', such that F' will
+   match more than 1 existing flow key, and create new actions list A' for F'
+6. Send loose flow modify for F' to switch
+7. Retrieve flow stats from switch
+8. Compare flow configurations returned by switch
+9. Test PASSED iff all flows sent to switch in steps 3 and 6 above, are
+   returned in step 7 above, each with correct (original or modified) action
+   list;
+   else test FAILED
+
+
+3.3  FLOW MODIFY 3
+------------------
+
+OVERVIEW
+- Strict modify of non-existent flow
+
+PRUPOSE
+- Verify that strict modify of a non-existent flow is equivalent to a flow add
+
+INPUTS
+None
+
+PROCESS
+1. Delete all flows from switch
+2. Send strict flow modify to switch
+3. Retrieve flows from switch
+4. Test PASSED iff single flow defined in step 2 above is returned in step 3
+   above; else test FAILED
+
+
+3.3.1 FLOW MODIFY 3_1
+---------------------
+
+OVERVIEW
+- No-op modify
+
+PURPOSE
+- Verify that modify of a flow with new actions same as old ones operates
+  correctly
+
+PARAMETERS
+None
+
+PROCESS
+1. Delete all flows from switch
+2. Send single flow mod, as strict modify, to switch
+3. Verify flow table in switch
+4. Send same flow mod, as strict modify, to switch
+5. Verify flow table in switch
+6. Test PASSED iff flow defined in step 2 and 4 above verified; else FAILED
+
+
+4.  FLOW DELETE
+===============
+
+4.1  FLOW DELETE 1
+------------------
+
+OVERVIEW
+- Strict delete of single flows
+
+PURPOSE
+- Verify correct operation of strict delete of single defined flow
+
+INPUTS
+- NUM_FLOWS: Number of flows to define; 0 => maximum number of flows, as
+  determined fro switch capabilities
+
+PROCESS
+1. Delete all flows from switch
+2. Generate NUM_FLOWS distinct flow configurations
+3. Send NUM_FLOWS flow adds to switch, for flows generated in step 2 above
+   - Flow mods with OFPFF_SEND_FLOW_REM = 0 (do not send remove message) and
+     OFPFF_CHECK_OVERLAP = 0 (do not check for overlap)
+4. Pick 1 defined flow F at random
+5. Send strict flow delete for F to switch
+6. Retrieve flow stats from switch
+7. Compare flow configurations returned by switch
+8. Test PASSED iff all flows sent to switch in step 3 above, less flow
+   removed in step 5 above, are returned in step 5 above; else test FAILED
+
+
+4.2  FLOW DELETE 2
+------------------
+
+OVERVIEW
+- Loose delete of flows
+
+PURPOSE
+- Verify correct operation of loose delete of multiple flows
+
+INPUTS
+- NUM_FLOWS: Number of flows to define; 0 => maximum number of flows, as
+  determined fro switch capabilities
+
+PROCESS
+1. Delete all flows from switch
+2. Generate NUM_FLOWS distinct flow configurations
+3. Send NUM_FLOWS flow adds to switch, for flows generated in step 2 above
+   - Flow mods with OFPFF_SEND_FLOW_REM = 0 (do not send remove message) and
+     OFPFF_CHECK_OVERLAP = 0 (do not check for overlap)
+4. Pick 1 defined flow F at random
+5. Wildcard out 1 qualifier in match of F, creating F', such that F' will
+   match more than 1 existing flow key
+6. Send loose flow delete for F' to switch
+7. Retrieve flow stats from switch
+8. Compare flow configurations returned by switch
+9. Test PASSED iff all flows sent to switch in step 3 above, less flows
+   removed in step 6 above (i.e. those that match F'), are returned in step
+   5 above;
+   else test FAILED
+
+
+4.4  FLOW DELETE 4
+------------------
+
+OVERVIEW
+- Flow removed messages
+
+PURPOSE
+- Verify that switch generates OFPT_FLOW_REMOVED/OFPRR_DELETE response
+  messages when deleting flows that were added with OFPFF_SEND_FLOW_REM flag
+
+INPUTS
+- NUM_FLOWS: Number of flows to define; 0 => maximum number of flows, as
+  determined fro switch capabilities
+
+PROCESS
+1. Delete all flows from switch
+2. Generate NUM_FLOWS distinct flow configurations
+3. Send NUM_FLOWS flow adds to switch, for flows generated in step 2 above
+   - Flow mods with OFPFF_SEND_FLOW_REM = 1 (do not send remove message) and
+     OFPFF_CHECK_OVERLAP = 0 (do not check for overlap)
+4. Pick 1 defined flow F at random
+5. Send strict flow delete for F to switch
+6. Verify that OFPT_FLOW_REMOVED/OFPRR_DELETE message is received from switch
+7. Retrieve flow stats from switch
+8. Compare flow configurations returned by switch
+9. Test PASSED iff all flows sent to switch in step 3 above, less flow
+   removed in step 5 above, are returned in step 5 above; else test FAILED
+
+
diff --git a/Fabric/Doc/docs/images/oftest_arch.png b/Fabric/Doc/docs/images/oftest_arch.png
new file mode 100644
index 0000000..e752d1b
--- /dev/null
+++ b/Fabric/Doc/docs/images/oftest_arch.png
Binary files differ
diff --git a/Fabric/LICENSE b/Fabric/LICENSE
new file mode 100644
index 0000000..44ebddd
--- /dev/null
+++ b/Fabric/LICENSE
@@ -0,0 +1,36 @@
+OpenFlow Test Framework
+
+Copyright (c) 2010 The Board of Trustees of The Leland Stanford 
+Junior University
+
+Except where otherwise noted, this software is distributed under
+the OpenFlow Software License.  See 
+http://www.openflowswitch.org/wp/legal/ for current details.
+
+We are making the OpenFlow specification and associated documentation
+(Software) available for public use and benefit with the expectation
+that others will use, modify and enhance the Software and contribute
+those enhancements back to the community. However, since we would like
+to make the Software available for broadest use, with as few
+restrictions as possible permission is hereby granted, free of charge,
+to any person obtaining a copy of this Software to deal in the
+Software under the copyrights without restriction, including without
+limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions: 
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software. 
+
+THE SOFTWARE IS PROVIDED -Y´AS IS¡, WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+
+The name and trademarks of copyright holder(s) may NOT be used in
+advertising or publicity pertaining to the Software or any derivatives
+without specific, written prior permission. 
diff --git a/Fabric/Project/seba-1.0.0 b/Fabric/Project/seba-1.0.0
new file mode 100644
index 0000000..b478ec8
--- /dev/null
+++ b/Fabric/Project/seba-1.0.0
@@ -0,0 +1,67 @@
+
+# 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.
+
+
+
+
+##########################################################################################
+###########################  CORD CERTIFICATION PROGRAM (CCP)   ########################## 
+##########################################################################################
+
+##############   This file lists the mandatory test cases to be executed  ################
+##################   for certifying a Fabric switch against SEBA1.0   ####################
+
+
+
+
+
+### Functional Test cases ###
+## Total #test cases - 19
+
+functional.FabricSW_OF_Bridging_TC_0001
+functional.FabricSW_OF_PacketInArp_TC_0005
+functional.FabricSW_OF_PacketInUDP_TC_0010
+functional.FabricSW_OF_L2FloodQinQ_TC_0015
+functional.FabricSW_OF_L2UnicastTagged_TC_0020
+functional.FabricSW_OF_EcmpGroupMod_TC_0025
+functional.FabricSW_OF_FloodGroupMod_TC_0030
+functional.FabricSW_OF_Mtu1500_TC_0035
+functional.FabricSW_OF__24ECMPL3_TC_0040
+functional.FabricSW_OF__24UcastTagged_TC_0045
+functional.FabricSW_OF__32ECMPL3_TC_0050
+functional.FabricSW_OF__32UcastTagged_TC_0055
+functional.FabricSW_OF_EAPOL_TC_0060
+functional.FabricSW_OF_ARP_TC_0065
+functional.FabricSW_OF_VLANPUSH_TC_0070
+functional.FabricSW_OF_LLDP_TC_0075
+functional.FabricSW_OF_BDDP_TC_0080
+functional.FabricSW_OF_VLANXConnect_Single_TC_0085
+#functional.FabricSW_OF_VLANXConnect_Multi_TC_0090
+#functional.FabricSW_OF_Counters_TC_0095
+
+
+
+### Operational Test cases ###
+## Total #test cases - 
+
+
+
+
+
+
+
+
+### Scalability Test cases ###
+## Total #test cases - 
diff --git a/Fabric/Tests/README b/Fabric/Tests/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Fabric/Tests/README
diff --git a/Fabric/Tests/cleanup_flows.py b/Fabric/Tests/cleanup_flows.py
new file mode 100755
index 0000000..dc45d0f
--- /dev/null
+++ b/Fabric/Tests/cleanup_flows.py
@@ -0,0 +1,43 @@
+
+# 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.
+
+
+"""
+Check README file
+"""
+import Queue
+
+from oftest import config
+import inspect
+import logging
+import oftest.base_tests as base_tests
+import ofp
+import time
+from oftest.oft12.testutils import delete_all_flows_one_table
+from oftest.testutils import *
+from accton_util import *
+from oftest.utils import *
+
+class CleanupAllFlows( base_tests.SimpleDataPlane ):
+    """
+    Clean-up all flows in the switch 
+    """
+
+    def runTest( self ):
+            logging.info( "Cleanup Start" )
+            delete_all_flows( self.controller )
+            delete_all_groups( self.controller )
+            logging.info( "Cleanup Completed" )
+
diff --git a/Fabric/Tests/functional.py b/Fabric/Tests/functional.py
new file mode 100755
index 0000000..aa3a5bb
--- /dev/null
+++ b/Fabric/Tests/functional.py
@@ -0,0 +1,4796 @@
+
+# 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.
+
+
+"""
+Check README file
+"""
+import Queue
+
+from oftest import config
+import inspect
+import logging
+import oftest.base_tests as base_tests
+import ofp
+import time
+from oftest.oft12.testutils import delete_all_flows_one_table
+from oftest.testutils import *
+from accton_util import *
+from oftest.utils import *
+
+   
+class FabricSW_OF_PacketInUDP_TC_0010( base_tests.SimpleDataPlane ):
+    """ 
+    Verify ACL rule for IP_PROTO=2 wont match a UDP packet and a rule for IP_PROTO=17 WILL match a UDP packet.
+    """
+
+    def runTest( self ):
+        try:
+            parsed_vlan_pkt = simple_udp_packet( pktlen=104, vlan_vid=0x1001, dl_vlan_enable=True )
+            vlan_pkt = str( parsed_vlan_pkt )
+            # create match
+            match = ofp.match( )
+            match.oxm_list.append( ofp.oxm.eth_type( 0x0800 ) )
+            match.oxm_list.append( ofp.oxm.ip_proto( 2 ) )
+            request = ofp.message.flow_add( table_id=60, cookie=42, match=match, instructions=[
+                ofp.instruction.apply_actions( actions=[
+                    ofp.action.output( port=ofp.OFPP_CONTROLLER, max_len=ofp.OFPCML_NO_BUFFER ) ] ), ],
+                    buffer_id=ofp.OFP_NO_BUFFER, priority=1 )
+            logging.info( "Inserting packet in flow to controller" )
+            self.controller.message_send( request )
+
+            for of_port in config[ "port_map" ].keys( ):
+                logging.info( "PacketInMiss test, port %d", of_port )
+                self.dataplane.send( of_port, vlan_pkt )
+
+                verify_no_packet_in( self, vlan_pkt, of_port )
+            delete_all_flows( self.controller )
+            do_barrier( self.controller )
+
+            match = ofp.match( )
+            match.oxm_list.append( ofp.oxm.eth_type( 0x0800 ) )
+            match.oxm_list.append( ofp.oxm.ip_proto( 17 ) )
+            request = ofp.message.flow_add( table_id=60, cookie=42, match=match, instructions=[
+                ofp.instruction.apply_actions( actions=[
+                    ofp.action.output( port=ofp.OFPP_CONTROLLER, max_len=ofp.OFPCML_NO_BUFFER ) ] ), ],
+                    buffer_id=ofp.OFP_NO_BUFFER, priority=1 )
+            logging.info( "Inserting packet in flow to controller" )
+            self.controller.message_send( request )
+            do_barrier( self.controller )
+
+            for of_port in config[ "port_map" ].keys( ):
+                logging.info( "PacketInMiss test, port %d", of_port )
+                self.dataplane.send( of_port, vlan_pkt )
+
+                verify_packet_in( self, vlan_pkt, of_port, ofp.OFPR_ACTION )
+
+                verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_all_groups( self.controller )
+
+@disabled
+class ArpNL2( base_tests.SimpleDataPlane ):
+    """
+    Needs a description, disabled for now. Also needs try/finally
+    """
+    def runTest( self ):
+        delete_all_flows( self.controller )
+        delete_all_groups( self.controller )
+
+        ports = sorted( config[ "port_map" ].keys( ) )
+        match = ofp.match( )
+        match.oxm_list.append( ofp.oxm.eth_type( 0x0806 ) )
+        request = ofp.message.flow_add( table_id=60, cookie=42, match=match, instructions=[
+            ofp.instruction.apply_actions( actions=[
+                ofp.action.output( port=ofp.OFPP_CONTROLLER, max_len=ofp.OFPCML_NO_BUFFER ) ] ), ],
+                buffer_id=ofp.OFP_NO_BUFFER, priority=40000 )
+        self.controller.message_send( request )
+        for port in ports:
+            add_one_l2_interface_group( self.controller, port, 1, False, False )
+            add_one_vlan_table_flow( self.controller, port, 1, flag=VLAN_TABLE_FLAG_ONLY_BOTH )
+            group_id = encode_l2_interface_group_id( 1, port )
+            add_bridge_flow( self.controller, [ 0x00, 0x12, 0x34, 0x56, 0x78, port ], 1, group_id, True )
+        do_barrier( self.controller )
+        parsed_arp_pkt = simple_arp_packet( )
+        arp_pkt = str( parsed_arp_pkt )
+
+        for out_port in ports:
+            self.dataplane.send( out_port, arp_pkt )
+            verify_packet_in( self, arp_pkt, out_port, ofp.OFPR_ACTION )
+            # change dest based on port number
+            mac_dst = '00:12:34:56:78:%02X' % out_port
+            for in_port in ports:
+                if in_port == out_port:
+                    continue
+                # change source based on port number to avoid packet-ins from learning
+                mac_src = '00:12:34:56:78:%02X' % in_port
+                parsed_pkt = simple_tcp_packet( eth_dst=mac_dst, eth_src=mac_src )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                for ofport in ports:
+                    if ofport in [ out_port ]:
+                        verify_packet( self, pkt, ofport )
+                    else:
+                        verify_no_packet( self, pkt, ofport )
+
+                verify_no_other_packets( self )
+
+class FabricSW_OF_PacketInArp_TC_0005( base_tests.SimpleDataPlane ):
+    """
+    Verify Packet-in message from eth_type 0x806 on ACL table
+    """
+
+    def runTest( self ):
+        try:
+            parsed_arp_pkt = simple_arp_packet( )
+            arp_pkt = str( parsed_arp_pkt )
+            # create match
+            match = ofp.match( )
+            match.oxm_list.append( ofp.oxm.eth_type( 0x0806 ) )
+            request = ofp.message.flow_add( table_id=60, cookie=42, match=match, instructions=[
+                ofp.instruction.apply_actions( actions=[
+                    ofp.action.output( port=ofp.OFPP_CONTROLLER, max_len=ofp.OFPCML_NO_BUFFER ) ] ), ],
+                    buffer_id=ofp.OFP_NO_BUFFER, priority=1 )
+
+            logging.info( "Inserting arp flow " )
+            self.controller.message_send( request )
+            do_barrier( self.controller )
+
+            for of_port in config[ "port_map" ].keys( ):
+                logging.info( "PacketInArp test, sending arp packet to port %d", of_port )
+                self.dataplane.send( of_port, arp_pkt )
+
+                verify_packet_in( self, arp_pkt, of_port, ofp.OFPR_ACTION )
+
+                verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_all_groups( self.controller )
+
+@disabled
+class PacketInIPTable( base_tests.SimpleDataPlane ):
+    """
+    Verify Packet-in message from IP table when controller action is used
+    Send a packet to each dataplane port and verify that a packet
+    in message is received from the controller for each
+    #todo verify you stop receiving after adding rule
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            ports = sorted( config[ "port_map" ].keys( ) )
+
+            for port in ports:
+                # add l2 interface group
+                vlan_id = port
+                add_one_l2_interface_group( self.controller, port, vlan_id=vlan_id, is_tagged=True,
+                        send_barrier=False )
+                dst_mac[ 5 ] = vlan_id
+                l3_msg = add_l3_unicast_group( self.controller, port, vlanid=vlan_id, id=vlan_id,
+                        src_mac=intf_src_mac, dst_mac=dst_mac )
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, vlan_id=vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                # add termination flow
+                add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                # add unicast routing flow
+                dst_ip = dip + (vlan_id << 8)
+                add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffff00, l3_msg.group_id,
+                        send_ctrl=True )
+                Groups.put( l3_msg.group_id )
+
+            do_barrier( self.controller )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            for in_port in ports:
+                mac_src = '00:00:00:22:22:%02X' % in_port
+                ip_src = '192.168.%02d.1' % in_port
+                for out_port in ports:
+                    if in_port == out_port:
+                        continue
+                    ip_dst = '192.168.%02d.1' % out_port
+                    parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=in_port,
+                            eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( parsed_pkt )
+                    self.dataplane.send( in_port, pkt )
+                    verify_packet_in( self, pkt, in_port, ofp.OFPR_ACTION )
+                    # verify_no_other_packets(self)
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+class FabricSW_OF_L2FloodQinQ_TC_0015( base_tests.SimpleDataPlane ):
+    """
+    Verify Vlan based flooding of QinQ based on its outer vlan
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            ports = sorted( config[ "port_map" ].keys( ) )
+            vlan_id = 100
+
+            for port in ports:
+                L2gid, l2msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, False )
+                add_one_vlan_table_flow( self.controller, port, vlan_id=vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                Groups.put( L2gid )
+
+            msg = add_l2_flood_group( self.controller, ports, vlan_id, vlan_id )
+            Groups.put( msg.group_id )
+            add_bridge_flow( self.controller, None, vlan_id, msg.group_id, True )
+            do_barrier( self.controller )
+
+            # verify flood
+            for ofport in ports:
+                # change dest based on port number
+                mac_src = '00:12:34:56:78:%02X' % ofport
+                parsed_pkt = simple_tcp_packet_two_vlan( pktlen=108, out_dl_vlan_enable=True,
+                        out_vlan_vid=vlan_id, in_dl_vlan_enable=True, in_vlan_vid=10,
+                        eth_dst='00:12:34:56:78:9a', eth_src=mac_src )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( ofport, pkt )
+                # self won't rx packet
+                verify_no_packet( self, pkt, ofport )
+                # others will rx packet
+                tmp_ports = list( ports )
+                tmp_ports.remove( ofport )
+                verify_packets( self, pkt, tmp_ports )
+
+            verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+
+@disabled
+class L2FloodTagged( base_tests.SimpleDataPlane ):
+    """
+    currently disabled; fix with try/finally
+    Test L2 flood to a vlan
+    Send a packet with unknown dst_mac and check if the packet is flooded to all ports except inport
+    """
+
+    def runTest( self ):
+        # Hashes Test Name and uses it as id for installing unique groups
+        vlan_id = abs( hash( inspect.stack( )[ 0 ][ 3 ] ) ) % (256)
+        print vlan_id
+
+        ports = sorted( config[ "port_map" ].keys( ) )
+
+        delete_all_flows( self.controller )
+        delete_all_groups( self.controller )
+
+        # Installing flows to avoid packet-in
+        for port in ports:
+            add_one_l2_interface_group( self.controller, port, vlan_id, True, False )
+            add_one_vlan_table_flow( self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+        msg = add_l2_flood_group( self.controller, ports, vlan_id, vlan_id )
+        add_bridge_flow( self.controller, None, vlan_id, msg.group_id, True )
+        do_barrier( self.controller )
+
+        # verify flood
+        for ofport in ports:
+            # change dest based on port number
+            pkt = str(
+                    simple_tcp_packet( dl_vlan_enable=True, vlan_vid=vlan_id, eth_dst='00:12:34:56:78:9a' ) )
+            self.dataplane.send( ofport, pkt )
+            # self won't rx packet
+            verify_no_packet( self, pkt, ofport )
+            # others will rx packet
+            tmp_ports = list( ports )
+            tmp_ports.remove( ofport )
+            verify_packets( self, pkt, tmp_ports )
+        verify_no_other_packets( self )
+
+
+class FabricSW_OF_L2UnicastTagged_TC_0020( base_tests.SimpleDataPlane ):
+    """ Verify Bridging works: match(VID, DST_MAC)> fwd(port) """
+
+    def runTest( self ):
+
+        Groups = Queue.LifoQueue( )
+        try:
+            ports = sorted( config[ "port_map" ].keys( ) )
+            vlan_id = 1;
+            for port in ports:
+                L2gid, l2msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, False )
+                add_one_vlan_table_flow( self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                Groups.put( L2gid )
+                add_bridge_flow( self.controller, [ 0x00, 0x12, 0x34, 0x56, 0x78, port ], vlan_id, L2gid,
+                        True )
+            do_barrier( self.controller )
+
+            for out_port in ports:
+                # change dest based on port number
+                mac_dst = '00:12:34:56:78:%02X' % out_port
+                for in_port in ports:
+                    if in_port == out_port:
+                        continue
+                    pkt = str( simple_tcp_packet( dl_vlan_enable=True, vlan_vid=vlan_id, eth_dst=mac_dst ) )
+                    self.dataplane.send( in_port, pkt )
+                    for ofport in ports:
+                        if ofport in [ out_port ]:
+                            verify_packet( self, pkt, ofport )
+                        else:
+                            verify_no_packet( self, pkt, ofport )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+class FabricSW_OF_Bridging_TC_0001( base_tests.SimpleDataPlane ):
+    """
+    Verify bridging works including flooding with different vlans
+    ports[0] has vlan 31 untagged
+    ports[1] has vlan 31 untagged (native) and vlan 41 tagged
+    ARP request should be flooded
+    ARP reply should be forwarded by bridging rule
+    Both arp messages should also be copied to controller
+    """
+
+    def runTest( self ):
+        Groupd = Queue.LifoQueue()
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+            ports = sorted( config[ "port_map" ].keys() )
+            vlan_p0_untagged = 31
+            vlan_p1_tagged = 31
+            vlan_p1_native = 41
+
+            #l2 interface groups and table 10 flows
+            L2p0gid, l2msg0 = add_one_l2_interface_group( self.controller, ports[0], vlan_p0_untagged,
+                                                          is_tagged=False, send_barrier=False )
+            add_one_vlan_table_flow( self.controller, ports[0], vlan_id=vlan_p0_untagged, flag=VLAN_TABLE_FLAG_ONLY_BOTH,
+                                     send_barrier=True)
+            L2p1gid, l2msg1 = add_one_l2_interface_group( self.controller, ports[1], vlan_p1_tagged,
+                                                          is_tagged=True, send_barrier=False )
+            add_one_vlan_table_flow( self.controller, ports[1], vlan_id=vlan_p1_tagged, flag=VLAN_TABLE_FLAG_ONLY_TAG,
+                                     send_barrier=True)
+            L2p1gid2, l2msg3 = add_one_l2_interface_group( self.controller, ports[1], vlan_p1_native,
+                                                          is_tagged=False, send_barrier=False )
+            add_one_vlan_table_flow( self.controller, ports[1], vlan_id=vlan_p1_native, flag=VLAN_TABLE_FLAG_ONLY_BOTH,
+                                     send_barrier=True)
+            #flooding groups
+            Floodmsg31 = add_l2_flood_group( self.controller, ports, vlan_p0_untagged, id=0 )
+            Floodmsg41 = add_l2_flood_group( self.controller, [ ports[1] ], vlan_p1_native, id=0 )
+
+            #add bridging flows for flooding groups
+            add_bridge_flow( self.controller, dst_mac=None, vlanid=vlan_p0_untagged, group_id=Floodmsg31.group_id )
+            add_bridge_flow( self.controller, dst_mac=None, vlanid=vlan_p1_native, group_id=Floodmsg41.group_id )
+            do_barrier( self.controller )
+
+            # add bridging flows for dstMac+vlan
+            add_bridge_flow( self.controller, [ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 ], vlan_p0_untagged, L2p0gid, True )
+            add_bridge_flow( self.controller, [ 0x00, 0x66, 0x77, 0x88, 0x99, 0xaa ], vlan_p1_tagged, L2p1gid, True )
+            add_bridge_flow( self.controller, [ 0x00, 0x66, 0x77, 0x88, 0x99, 0xaa ], vlan_p1_native, L2p1gid2, True )
+
+            # add terminationMac flow
+            router_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            if config["switch_type"] == "qmx":
+                add_termination_flow( self.controller, 0, 0x0800, router_mac, vlan_p0_untagged )
+                add_termination_flow( self.controller, 0, 0x0800, router_mac, vlan_p1_native )
+            else:
+                add_termination_flow( self.controller, ports[0], 0x0800, router_mac, vlan_p0_untagged )
+                add_termination_flow( self.controller, ports[1], 0x0800, router_mac, vlan_p1_tagged )
+                add_termination_flow( self.controller, ports[1], 0x0800, router_mac, vlan_p1_native )
+
+            # add acl rule for arp
+            match = ofp.match( )
+            match.oxm_list.append( ofp.oxm.eth_type( 0x0806 ) )
+            request = ofp.message.flow_add( table_id=60, cookie=42, match=match, instructions=[
+                ofp.instruction.apply_actions( actions=[
+                    ofp.action.output( port=ofp.OFPP_CONTROLLER, max_len=ofp.OFPCML_NO_BUFFER ) ] ), ],
+                    buffer_id=ofp.OFP_NO_BUFFER, priority=1 )
+            self.controller.message_send( request )
+            do_barrier( self.controller )
+
+            #acl rule for gateway ip
+            match = ofp.match( )
+            match.oxm_list.append( ofp.oxm.eth_type( 0x0800 ) )
+            match.oxm_list.append( ofp.oxm.ipv4_dst( 0xc0a80003 ) )
+            request = ofp.message.flow_add( table_id=60, cookie=42, match=match, instructions=[
+                ofp.instruction.apply_actions( actions=[
+                    ofp.action.output( port=ofp.OFPP_CONTROLLER, max_len=ofp.OFPCML_NO_BUFFER ) ] ),
+                ofp.instruction.clear_actions() ],
+                    buffer_id=ofp.OFP_NO_BUFFER, priority=1 )
+            self.controller.message_send( request )
+            do_barrier( self.controller )
+
+            # send ARP request
+            parsed_arp_pkt = simple_arp_packet(pktlen=80,
+                                               eth_dst='ff:ff:ff:ff:ff:ff',
+                                               eth_src='00:66:77:88:99:aa',
+                                               vlan_vid=vlan_p1_tagged,
+                                               vlan_pcp=0,
+                                               arp_op=1,
+                                               ip_snd='192.168.0.2',
+                                               ip_tgt='192.168.0.1',
+                                               hw_snd='00:66:77:88:99:aa',
+                                               hw_tgt='00:00:00:00:00:00')
+            arp_pkt_to_send = str( parsed_arp_pkt )
+            logging.info( "sending arp request to port %d", ports[1] )
+            self.dataplane.send( ports[1], arp_pkt_to_send )
+            verify_packet_in( self, arp_pkt_to_send, ports[1], ofp.OFPR_ACTION )
+            parsed_arp_pkt_untagged = simple_arp_packet(pktlen=76,
+                                               eth_dst='ff:ff:ff:ff:ff:ff',
+                                               eth_src='00:66:77:88:99:aa',
+                                               vlan_vid=0,
+                                               vlan_pcp=0,
+                                               arp_op=1,
+                                               ip_snd='192.168.0.2',
+                                               ip_tgt='192.168.0.1',
+                                               hw_snd='00:66:77:88:99:aa',
+                                               hw_tgt='00:00:00:00:00:00')
+            arp_pkt_dest = str( parsed_arp_pkt_untagged )
+            verify_packet( self, arp_pkt_dest, ports[0] )
+            #verify_no_other_packets( self )
+
+            # send ARP reply
+            parsed_arp_pkt = simple_arp_packet(pktlen=76,
+                                               eth_dst='00:66:77:88:99:aa',
+                                               eth_src='00:11:22:33:44:55',
+                                               vlan_vid=0,
+                                               vlan_pcp=0,
+                                               arp_op=2,
+                                               ip_snd='192.168.0.1',
+                                               ip_tgt='192.168.0.2',
+                                               hw_snd='00:11:22:33:44:55',
+                                               hw_tgt='00:66:77:88:99:aa')
+            arp_pkt_to_send = str( parsed_arp_pkt )
+            logging.info( "sending arp reply to port %d", ports[0] )
+            self.dataplane.send( ports[0], arp_pkt_to_send )
+            verify_packet_in( self, arp_pkt_to_send, ports[0], ofp.OFPR_ACTION )
+            parsed_arp_pkt_tagged = simple_arp_packet(pktlen=80,
+                                               eth_dst='00:66:77:88:99:aa',
+                                               eth_src='00:11:22:33:44:55',
+                                               vlan_vid=vlan_p1_tagged,
+                                               vlan_pcp=0,
+                                               arp_op=2,
+                                               ip_snd='192.168.0.1',
+                                               ip_tgt='192.168.0.2',
+                                               hw_snd='00:11:22:33:44:55',
+                                               hw_tgt='00:66:77:88:99:aa')
+            arp_pkt_dest = str( parsed_arp_pkt_tagged )
+            verify_packet( self, arp_pkt_dest, ports[1] )
+
+        finally:
+            delete_all_flows( self.controller )
+            delete_all_groups( self.controller )
+            #print("done")
+
+
+
+class FabricSW_OF_Mtu1500_TC_0035( base_tests.SimpleDataPlane ):
+    """
+    Verifies basic mtu limits
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            ports = sorted( config[ "port_map" ].keys( ) )
+            vlan_id = 18
+            for port in ports:
+                L2gid, msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, False )
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                Groups.put( L2gid )
+                add_bridge_flow( self.controller, [ 0x00, 0x12, 0x34, 0x56, 0x78, port ], vlan_id, L2gid,
+                        True )
+            do_barrier( self.controller )
+
+            for out_port in ports:
+                # change dest based on port number
+                mac_dst = '00:12:34:56:78:%02X' % out_port
+                for in_port in ports:
+                    if in_port == out_port:
+                        continue
+                    pkt = str( simple_tcp_packet( pktlen=1500, dl_vlan_enable=True, vlan_vid=vlan_id,
+                            eth_dst=mac_dst ) )
+                    self.dataplane.send( in_port, pkt )
+                    for ofport in ports:
+                        if ofport in [ out_port ]:
+                            verify_packet( self, pkt, ofport )
+                        else:
+                            verify_no_packet( self, pkt, ofport )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+class FabricSW_OF__32UcastTagged_TC_0055( base_tests.SimpleDataPlane ):
+    """ Verify /32 IP forwarding to L3 Unicast-> L2Interface"""
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            test_id = 26
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            ports = config[ "port_map" ].keys( )
+            for port in ports:
+                vlan_id = port + test_id
+                # add l2 interface group and l3 unicast group
+                l2gid, msg = add_one_l2_interface_group( self.controller, port, vlan_id=vlan_id,
+                        is_tagged=True, send_barrier=False )
+                dst_mac[ 5 ] = vlan_id
+                l3_msg = add_l3_unicast_group( self.controller, port, vlanid=vlan_id, id=vlan_id,
+                        src_mac=intf_src_mac, dst_mac=dst_mac )
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                # add unicast routing flow
+                dst_ip = dip + (vlan_id << 8)
+                add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, l3_msg.group_id )
+                Groups.put( l2gid )
+                Groups.put( l3_msg.group_id )
+            do_barrier( self.controller )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            for in_port in ports:
+                mac_src = '00:00:00:22:32:%02X' % (test_id + in_port)
+                ip_src = '192.168.%02d.1' % (test_id + in_port)
+                for out_port in ports:
+                    if in_port == out_port:
+                        continue
+                    ip_dst = '192.168.%02d.1' % (test_id + out_port)
+                    parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True,
+                            vlan_vid=(test_id + in_port), eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64,
+                            ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( parsed_pkt )
+                    self.dataplane.send( in_port, pkt )
+                    # build expected packet
+                    mac_dst = '00:00:00:22:22:%02X' % (test_id + out_port)
+                    exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True,
+                            vlan_vid=(test_id + out_port), eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=63,
+                            ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( exp_pkt )
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class _32VPN( base_tests.SimpleDataPlane ):
+    """
+    Verify /32 routing rule -> MPLS_VPN_Label -> MPLSInterface -> L2Interface
+    No ECMP group used
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            ports = config[ "port_map" ].keys( )
+            for port in ports:
+                # add l2 interface group
+                id = port
+                vlan_id = port
+                l2_gid, l2_msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, True )
+                dst_mac[ 5 ] = vlan_id
+                # add MPLS interface group
+                mpls_gid, mpls_msg = add_mpls_intf_group( self.controller, l2_gid, dst_mac, intf_src_mac,
+                        vlan_id, id )
+                # add MPLS L3 VPN group
+                mpls_label_gid, mpls_label_msg = add_mpls_label_group( self.controller,
+                        subtype=OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL, index=id, ref_gid=mpls_gid,
+                        push_mpls_header=True, set_mpls_label=port, set_bos=1, set_ttl=32 )
+                do_barrier( self.controller )
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, vrf=2,
+                        flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                # add routing flow
+                dst_ip = dip + (vlan_id << 8)
+                add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, mpls_label_gid, vrf=2 )
+                Groups._put( l2_gid )
+                Groups._put( mpls_gid )
+                Groups._put( mpls_label_gid )
+            do_barrier( self.controller )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            for in_port in ports:
+                ip_src = '192.168.%02d.1' % (in_port)
+                for out_port in ports:
+                    if in_port == out_port:
+                        continue
+                    ip_dst = '192.168.%02d.1' % (out_port)
+                    parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=(in_port),
+                            eth_dst=switch_mac, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( parsed_pkt )
+                    self.dataplane.send( in_port, pkt )
+                    # build expect packet
+                    mac_dst = '00:00:00:22:22:%02X' % (out_port)
+                    label = (out_port, 0, 1, 32)
+                    exp_pkt = mpls_packet( pktlen=104, dl_vlan_enable=True, vlan_vid=(out_port), ip_ttl=63,
+                            ip_src=ip_src, ip_dst=ip_dst, eth_dst=mac_dst, eth_src=switch_mac,
+                            label=[ label ] )
+                    pkt = str( exp_pkt )
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class _32EcmpVpn( base_tests.SimpleDataPlane ):
+    """
+    Verify /32 routing rule -> L3 ECMP -> MPLS_VPN_Label -> MPLSInterface -> L2Interface
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            ports = config[ "port_map" ].keys( )
+            for port in ports:
+                # add l2 interface group
+                id = port
+                vlan_id = port
+                l2_gid, l2_msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, True )
+                dst_mac[ 5 ] = vlan_id
+                # add MPLS interface group
+                mpls_gid, mpls_msg = add_mpls_intf_group( self.controller, l2_gid, dst_mac, intf_src_mac,
+                        vlan_id, id )
+                # add MPLS L3 VPN group
+                mpls_label_gid, mpls_label_msg = add_mpls_label_group( self.controller,
+                        subtype=OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL, index=id, ref_gid=mpls_gid,
+                        push_mpls_header=True, set_mpls_label=port, set_bos=1, set_ttl=32 )
+                ecmp_msg = add_l3_ecmp_group( self.controller, vlan_id, [ mpls_label_gid ] )
+                do_barrier( self.controller )
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, vrf=0,
+                        flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                # add routing flow
+                dst_ip = dip + (vlan_id << 8)
+                add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, ecmp_msg.group_id )
+                Groups._put( l2_gid )
+                Groups._put( mpls_gid )
+                Groups._put( mpls_label_gid )
+                Groups._put( ecmp_msg.group_id )
+            do_barrier( self.controller )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            for in_port in ports:
+                ip_src = '192.168.%02d.1' % (in_port)
+                for out_port in ports:
+                    if in_port == out_port:
+                        continue
+                    ip_dst = '192.168.%02d.1' % (out_port)
+                    parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=(in_port),
+                            eth_dst=switch_mac, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( parsed_pkt )
+                    self.dataplane.send( in_port, pkt )
+                    # build expect packet
+                    mac_dst = '00:00:00:22:22:%02X' % (out_port)
+                    label = (out_port, 0, 1, 32)
+                    exp_pkt = mpls_packet( pktlen=104, dl_vlan_enable=True, vlan_vid=(out_port), ip_ttl=63,
+                            ip_src=ip_src, ip_dst=ip_dst, eth_dst=mac_dst, eth_src=switch_mac,
+                            label=[ label ] )
+                    pkt = str( exp_pkt )
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+@disabled
+class One_32EcmpVpn( base_tests.SimpleDataPlane ):
+    """
+    Verify /32 routing rule -> L3 ECMP -> MPLS_VPN_Label -> MPLSInterface -> L2Interface
+    in only one direction
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            ports = config[ "port_map" ].keys( )
+            # add l2 interface group
+            id = ports[1]
+            in_offset = 19
+            out_offset = 20
+            vlan_id = ports[1] + out_offset
+            l2_gid, l2_msg = add_one_l2_interface_group( self.controller, ports[1], vlan_id, True, True )
+            dst_mac[ 5 ] = ports[1]
+            # add MPLS interface group
+            mpls_gid, mpls_msg = add_mpls_intf_group( self.controller, l2_gid, dst_mac, intf_src_mac,
+                                                      vlan_id, id )
+            # add MPLS L3 VPN group
+            mpls_label_gid, mpls_label_msg = add_mpls_label_group( self.controller,
+                        subtype=OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL, index=id, ref_gid=mpls_gid,
+                        push_mpls_header=True, set_mpls_label=ports[1] + out_offset, set_bos=1, set_ttl=32 )
+            # add ECMP group
+            ecmp_msg = add_l3_ecmp_group( self.controller, vlan_id, [ mpls_label_gid ] )
+            do_barrier( self.controller )
+            # add vlan flow table
+            add_one_vlan_table_flow( self.controller, ports[0], 1, vlan_id=ports[0] + in_offset, vrf=0,
+                                     flag=VLAN_TABLE_FLAG_ONLY_TAG )
+            # add termination flow
+            if config["switch_type"] == "qmx":
+                add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlanid=ports[0] + in_offset )
+            else:
+                add_termination_flow( self.controller, ports[0], 0x0800, intf_src_mac, vlanid=ports[0] + in_offset )
+            # add routing flow
+            dst_ip = dip + (vlan_id << 8)
+            add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, ecmp_msg.group_id, send_barrier=True )
+            Groups._put( l2_gid )
+            Groups._put( mpls_gid )
+            Groups._put( mpls_label_gid )
+            Groups._put( ecmp_msg.group_id )
+
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            in_port = ports[0]
+            out_port = ports[1]
+            ip_src = '192.168.%02d.1' % (in_port)
+            ip_dst = '192.168.%02d.1' % (out_port+out_offset)
+            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=(in_port + in_offset),
+                                            eth_dst=switch_mac, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+            pkt = str( parsed_pkt )
+            self.dataplane.send( in_port, pkt )
+            # build expect packet
+            mac_dst = '00:00:00:22:22:%02X' % (out_port)
+            label = (out_port+out_offset, 0, 1, 32)
+            exp_pkt = mpls_packet( pktlen=104, dl_vlan_enable=True, vlan_vid=(out_port + out_offset), ip_ttl=63,
+                                   ip_src=ip_src, ip_dst=ip_dst, eth_dst=mac_dst, eth_src=switch_mac,
+                                   label=[ label ] )
+            pkt = str( exp_pkt )
+            verify_packet( self, pkt, out_port )
+            #verify_no_other_packets( self )
+
+        finally:
+            delete_all_flows( self.controller )
+            delete_group(self.controller, ecmp_msg.group_id)
+            delete_group(self.controller, mpls_label_gid)
+            delete_group(self.controller, mpls_gid)
+            delete_group(self.controller, l2_gid)
+
+
+class FabricSW_OF__32ECMPL3_TC_0050( base_tests.SimpleDataPlane ):
+    """
+    Verifies /32 IP routing and ECMP with no label push
+    IP -> L3ECMP -> L3Unicast -> L2Interface
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            # Hashes Test Name and uses it as id for installing unique groups
+            ports = config[ "port_map" ].keys( )
+            for port in ports:
+                vlan_id = port
+                id = port
+                # add l2 interface group
+                l2_gid, msg = add_one_l2_interface_group( self.controller, port, vlan_id=vlan_id,
+                        is_tagged=True, send_barrier=False )
+                dst_mac[ 5 ] = vlan_id
+                l3_msg = add_l3_unicast_group( self.controller, port, vlanid=vlan_id, id=id,
+                        src_mac=intf_src_mac, dst_mac=dst_mac )
+                ecmp_msg = add_l3_ecmp_group( self.controller, id, [ l3_msg.group_id ] )
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                # add unicast routing flow
+                dst_ip = dip + (vlan_id << 8)
+                add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, ecmp_msg.group_id )
+                Groups._put( l2_gid )
+                Groups._put( l3_msg.group_id )
+                Groups._put( ecmp_msg.group_id )
+            do_barrier( self.controller )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            for in_port in ports:
+                mac_src = '00:00:00:22:22:%02X' % in_port
+                ip_src = '192.168.%02d.1' % in_port
+                for out_port in ports:
+                    if in_port == out_port:
+                        continue
+                    ip_dst = '192.168.%02d.1' % out_port
+                    parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=in_port,
+                            eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( parsed_pkt )
+                    self.dataplane.send( in_port, pkt )
+                    # build expected packet
+                    mac_dst = '00:00:00:22:22:%02X' % out_port
+                    exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=out_port,
+                            eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=63, ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( exp_pkt )
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class One_32ECMPL3( base_tests.SimpleDataPlane ):
+    """
+    Verifies /32 IP routing and ECMP with no label push
+    IP -> L3ECMP -> L3Unicast -> L2Interface
+    in only one direction
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            # Hashes Test Name and uses it as id for installing unique groups
+            ports = config[ "port_map" ].keys( )
+            inport = ports[0]
+            outport = ports[1]
+            in_offset = 19
+            out_offset = 20
+            vlan_id = outport + out_offset
+            id = outport
+            # add l2 interface group, l3 unicast and ecmp group for outport
+            l2_gid, msg = add_one_l2_interface_group( self.controller, outport, vlan_id=vlan_id,
+                                                      is_tagged=True, send_barrier=False )
+            dst_mac[ 5 ] = outport
+            l3_msg = add_l3_unicast_group( self.controller, outport, vlanid=vlan_id, id=id,
+                                           src_mac=intf_src_mac, dst_mac=dst_mac )
+            ecmp_msg = add_l3_ecmp_group( self.controller, id, [ l3_msg.group_id ] )
+            # add vlan flow table
+            add_one_vlan_table_flow( self.controller, of_port=inport, vlan_id=inport+in_offset, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+            # add termination flow
+            if config["switch_type"] == "qmx":
+                add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlanid=inport+in_offset )
+            else:
+                add_termination_flow( self.controller, in_port=inport, eth_type=0x0800, dst_mac=intf_src_mac, vlanid=inport+in_offset )
+            # add unicast routing flow
+            dst_ip = dip + (vlan_id << 8)
+            add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, ecmp_msg.group_id, send_barrier=True )
+            Groups._put( l2_gid )
+            Groups._put( l3_msg.group_id )
+            Groups._put( ecmp_msg.group_id )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            mac_src = '00:00:00:22:22:%02X' % inport
+            ip_src = '192.168.%02d.1' % inport
+            ip_dst = '192.168.%02d.1' % (outport+out_offset)
+            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=inport+in_offset,
+                                            eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+            pkt = str( parsed_pkt )
+            self.dataplane.send( inport, pkt )
+            # build expected packet
+            mac_dst = '00:00:00:22:22:%02X' % outport
+            exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=outport+out_offset,
+                                         eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=63, ip_src=ip_src, ip_dst=ip_dst )
+            pkt = str( exp_pkt )
+            verify_packet( self, pkt, outport )
+            verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+
+
+@disabled
+class _24VPN( base_tests.SimpleDataPlane ):
+    """  Verify MPLS IP VPN Initiation from /32 rule without using ECMP  """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            ports = config[ "port_map" ].keys( )
+            for port in ports:
+                # add l2 interface group
+                id = port
+                vlan_id = port
+                l2_gid, l2_msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, True )
+                dst_mac[ 5 ] = vlan_id
+                # add MPLS interface group
+                mpls_gid, mpls_msg = add_mpls_intf_group( self.controller, l2_gid, dst_mac, intf_src_mac,
+                        vlan_id, id )
+                # add MPLS L3 VPN group
+                mpls_label_gid, mpls_label_msg = add_mpls_label_group( self.controller,
+                        subtype=OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL, index=id, ref_gid=mpls_gid,
+                        push_mpls_header=True, set_mpls_label=port, set_bos=1, set_ttl=32 )
+                # ecmp_msg=add_l3_ecmp_group(self.controller, vlan_id, [mpls_label_gid])
+                do_barrier( self.controller )
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, vrf=0,
+                        flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                # add routing flow
+                dst_ip = dip + (vlan_id << 8)
+                add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffff00, mpls_label_gid )
+                Groups._put( l2_gid )
+                Groups._put( mpls_gid )
+                Groups._put( mpls_label_gid )
+            do_barrier( self.controller )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            for in_port in ports:
+                ip_src = '192.168.%02d.1' % (in_port)
+                for out_port in ports:
+                    if in_port == out_port:
+                        continue
+                    ip_dst = '192.168.%02d.1' % (out_port)
+                    parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=(in_port),
+                            eth_dst=switch_mac, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( parsed_pkt )
+                    self.dataplane.send( in_port, pkt )
+                    # build expect packet
+                    mac_dst = '00:00:00:22:22:%02X' % (out_port)
+                    label = (out_port, 0, 1, 32)
+                    exp_pkt = mpls_packet( pktlen=104, dl_vlan_enable=True, vlan_vid=(out_port), ip_ttl=63,
+                            ip_src=ip_src, ip_dst=ip_dst, eth_dst=mac_dst, eth_src=switch_mac,
+                            label=[ label ] )
+                    pkt = str( exp_pkt )
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class _24EcmpVpn( base_tests.SimpleDataPlane ):
+    """  Verify MPLS IP VPN Initiation from /24 rule using ECMP  """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            ports = config[ "port_map" ].keys( )
+            for port in ports:
+                # add l2 interface group
+                id = port
+                vlan_id = id
+                l2_gid, l2_msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, True )
+                dst_mac[ 5 ] = vlan_id
+                # add MPLS interface group
+                mpls_gid, mpls_msg = add_mpls_intf_group( self.controller, l2_gid, dst_mac, intf_src_mac,
+                        vlan_id, id )
+                # add MPLS L3 VPN group
+                mpls_label_gid, mpls_label_msg = add_mpls_label_group( self.controller,
+                        subtype=OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL, index=id, ref_gid=mpls_gid,
+                        push_mpls_header=True, set_mpls_label=port, set_bos=1, set_ttl=32 )
+                ecmp_msg = add_l3_ecmp_group( self.controller, id, [ mpls_label_gid ] )
+                do_barrier( self.controller )
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, vrf=0,
+                        flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                # add routing flow
+                dst_ip = dip + (vlan_id << 8)
+                # add_unicast_routing_flow(self.controller, 0x0800, dst_ip, 0, mpls_label_gid, vrf=2)
+                add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffff00, ecmp_msg.group_id,
+                        vrf=0 )
+                Groups._put( l2_gid )
+                Groups._put( mpls_gid )
+                Groups._put( mpls_label_gid )
+                Groups._put( ecmp_msg.group_id )
+
+            do_barrier( self.controller )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            for in_port in ports:
+                mac_src = '00:00:00:22:22:%02X' % (in_port)
+                ip_src = '192.168.%02d.1' % (in_port)
+                for out_port in ports:
+                    if in_port == out_port:
+                        continue
+                    ip_dst = '192.168.%02d.1' % (out_port)
+                    parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=(in_port),
+                            eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( parsed_pkt )
+                    self.dataplane.send( in_port, pkt )
+                    # build expect packet
+                    mac_dst = '00:00:00:22:22:%02X' % out_port
+                    label = (out_port, 0, 1, 32)
+                    exp_pkt = mpls_packet( pktlen=104, dl_vlan_enable=True, vlan_vid=(out_port), ip_ttl=63,
+                            ip_src=ip_src, ip_dst=ip_dst, eth_dst=mac_dst, eth_src=switch_mac,
+                            label=[ label ] )
+                    pkt = str( exp_pkt )
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+class FabricSW_OF_FloodGroupMod_TC_0030( base_tests.SimpleDataPlane ):
+    """ Modify a referenced flood group """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            ports = sorted( config[ "port_map" ].keys( ) )
+            vlan_id = 1
+
+            for port in ports:
+                L2gid, l2msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, False )
+                add_one_vlan_table_flow( self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                Groups.put( L2gid )
+
+            msg = add_l2_flood_group( self.controller, ports, vlan_id, vlan_id )
+            Groups.put( msg.group_id )
+            add_bridge_flow( self.controller, None, vlan_id, msg.group_id, True )
+            do_barrier( self.controller )
+            # verify flood
+            for ofport in ports:
+                # change dest based on port number
+                mac_src = '00:12:34:56:78:%02X' % ofport
+                parsed_pkt = simple_tcp_packet_two_vlan( pktlen=108, out_dl_vlan_enable=True,
+                        out_vlan_vid=vlan_id, in_dl_vlan_enable=True, in_vlan_vid=10,
+                        eth_dst='00:12:34:56:78:9a', eth_src=mac_src )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( ofport, pkt )
+                # self won't rx packet
+                verify_no_packet( self, pkt, ofport )
+                # others will rx packet
+                tmp_ports = list( ports )
+                tmp_ports.remove( ofport )
+                verify_packets( self, pkt, tmp_ports )
+            verify_no_other_packets( self )
+            msg = mod_l2_flood_group( self.controller, [ ports[ 0 ] ], vlan_id, vlan_id )
+            mac_src = '00:12:34:56:78:%02X' % ports[ 1 ]
+            parsed_pkt = simple_tcp_packet_two_vlan( pktlen=108, out_dl_vlan_enable=True,
+                    out_vlan_vid=vlan_id, in_dl_vlan_enable=True, in_vlan_vid=10, eth_dst='00:12:34:56:78:9a',
+                    eth_src=mac_src )
+            pkt = str( parsed_pkt )
+            self.dataplane.send( ports[ 1 ], pkt )
+            verify_packets( self, pkt, [ ports[ 0 ] ] )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+class FabricSW_OF__24ECMPL3_TC_0040( base_tests.SimpleDataPlane ):
+    """ Verifies /24 IP routing using ECMP -> L3U -> L2I """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            # Hashes Test Name and uses it as id for installing unique groups
+            ports = config[ "port_map" ].keys( )
+            for port in ports:
+                vlan_id = port
+                id = port
+                # add l2 interface group
+                l2_gid, msg = add_one_l2_interface_group( self.controller, port, vlan_id=vlan_id,
+                        is_tagged=True, send_barrier=False )
+                dst_mac[ 5 ] = vlan_id
+                l3_msg = add_l3_unicast_group( self.controller, port, vlanid=vlan_id, id=id,
+                        src_mac=intf_src_mac, dst_mac=dst_mac )
+                ecmp_msg = add_l3_ecmp_group( self.controller, id, [ l3_msg.group_id ] )
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                # add unicast routing flow
+                dst_ip = dip + (vlan_id << 8)
+                add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffff00, ecmp_msg.group_id )
+                Groups._put( l2_gid )
+                Groups._put( l3_msg.group_id )
+                Groups._put( ecmp_msg.group_id )
+            do_barrier( self.controller )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            for in_port in ports:
+                mac_src = '00:00:00:22:22:%02X' % in_port
+                ip_src = '192.168.%02d.1' % in_port
+                for out_port in ports:
+                    if in_port == out_port:
+                        continue
+                    ip_dst = '192.168.%02d.1' % out_port
+                    parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=in_port,
+                            eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( parsed_pkt )
+                    self.dataplane.send( in_port, pkt )
+                    # build expected packet
+                    mac_dst = '00:00:00:22:22:%02X' % out_port
+                    exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=out_port,
+                            eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=63, ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( exp_pkt )
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+@disabled
+class MPLSBUG( base_tests.SimpleDataPlane ):
+    """
+    Needs a description or needs to be removed
+    """
+    def runTest( self ):
+        if len( config[ "port_map" ] ) < 2:
+            logging.info( "Port count less than 2, can't run this case" )
+            return
+        intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+        dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+        dip = 0xc0a80001
+        Groups = Queue.LifoQueue( )
+        ports = config[ "port_map" ].keys( )
+        for port in ports:
+            # add l2 interface group
+            vlan_id = port
+            l2_gid, l2_msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, False )
+            dst_mac[ 5 ] = vlan_id
+            # add L3 Unicast  group
+            l3_msg = add_l3_unicast_group( self.controller, port, vlanid=vlan_id, id=vlan_id,
+                    src_mac=intf_src_mac, dst_mac=dst_mac )
+            # add vlan flow table
+            add_one_vlan_table_flow( self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_BOTH )
+            # add termination flow
+            if config["switch_type"] == "qmx":
+                add_termination_flow( self.controller, 0, 0x08847, intf_src_mac, vlan_id, goto_table=24 )
+            else:
+                add_termination_flow( self.controller, port, 0x8847, intf_src_mac, vlan_id, goto_table=24 )
+            # add mpls flow
+            add_mpls_flow( self.controller, l3_msg.group_id, port )
+            # add termination flow
+            add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+            # add unicast routing flow
+            dst_ip = dip + (vlan_id << 8)
+            add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, l3_msg.group_id )
+            Groups._put( l2_gid )
+            Groups._put( l3_msg.group_id )
+        do_barrier( self.controller )
+
+        switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+        for in_port in ports:
+            mac_src = '00:00:00:22:22:%02X' % in_port
+            ip_src = '192.168.%02d.1' % in_port
+            for out_port in ports:
+                if in_port == out_port:
+                    continue
+                ip_dst = '192.168.%02d.1' % out_port
+                switch_mac = "00:00:00:cc:cc:cc"
+                label = (out_port, 0, 1, 32)
+                parsed_pkt = mpls_packet( pktlen=104, dl_vlan_enable=True, vlan_vid=in_port, ip_src=ip_src,
+                        ip_dst=ip_dst, eth_dst=switch_mac, eth_src=mac_src, label=[ label ] )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                # build expect packet
+                mac_dst = '00:00:00:22:22:%02X' % out_port
+                exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=out_port,
+                        eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=31, ip_src=ip_src, ip_dst=ip_dst )
+                pkt = str( exp_pkt )
+                verify_packet( self, pkt, out_port )
+                verify_no_other_packets( self )
+
+                parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=in_port,
+                        eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+                # build expected packet
+                mac_dst = '00:00:00:22:22:%02X' % out_port
+                exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=out_port,
+                        eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=63, ip_src=ip_src, ip_dst=ip_dst )
+                pkt = str( exp_pkt )
+                verify_packet( self, pkt, out_port )
+                verify_no_other_packets( self )
+        delete_all_flows( self.controller )
+        delete_groups( self.controller, Groups )
+
+class L3McastToL3( base_tests.SimpleDataPlane ):
+    """
+    Mcast routing, in this test case the traffic comes in tagged.
+    port+1 is used as ingress vlan_id. The packet goes out tagged on
+    different ports. 4094-port is used as egress vlan_id.
+    """
+    def runTest( self ):
+        """
+        port1 (vlan 300)-> All Ports (vlan 300)
+        """
+        Groups = Queue.LifoQueue( )
+        try:
+        # We can forward on the in_port but egress_vlan has to be different from ingress_vlan
+            if len( config[ "port_map" ] ) < 1:
+                logging.info( "Port count less than 1, can't run this case" )
+                assert (False)
+                return
+            ports      = config[ "port_map" ].keys( )
+            dst_ip_str = "224.0.0.1"
+            (
+                port_to_in_vlan,
+                port_to_out_vlan,
+                port_to_src_mac_str,
+                port_to_dst_mac_str,
+                port_to_src_ip,
+                port_to_src_ip_str,
+                port_to_intf_src_mac_str,
+                Groups) = fill_mcast_pipeline_L3toL3(
+                self.controller,
+                logging,
+                ports,
+                is_ingress_tagged   = True,
+                is_egress_tagged    = True,
+                is_vlan_translated  = True,
+                is_max_vlan         = False
+                )
+
+            for in_port in ports:
+
+                parsed_pkt = simple_udp_packet(
+                    pktlen         = 100,
+                    dl_vlan_enable = True,
+                    vlan_vid       = port_to_in_vlan[in_port],
+                    eth_dst        = port_to_dst_mac_str[in_port],
+                    eth_src        = port_to_src_mac_str[in_port],
+                    ip_ttl         = 64,
+                    ip_src         = port_to_src_ip_str[in_port],
+                    ip_dst         = dst_ip_str
+                    )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                for out_port in ports:
+
+                    parsed_pkt = simple_udp_packet(
+                        pktlen         = 100,
+                        dl_vlan_enable = True,
+                        vlan_vid       = port_to_out_vlan[out_port],
+                        eth_dst        = port_to_dst_mac_str[in_port],
+                        eth_src        = port_to_intf_src_mac_str[out_port],
+                        ip_ttl         = 63,
+                        ip_src         = port_to_src_ip_str[in_port],
+                        ip_dst         = dst_ip_str
+                        )
+                    pkt = str( parsed_pkt )
+                    verify_packet( self, pkt, out_port )
+
+                verify_no_other_packets( self )
+
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class L3McastToL2UntagToUntag( base_tests.SimpleDataPlane ):
+    """
+    Fails on alternate runs
+    Mcast routing, in this test case the traffic is untagged.
+    4094 is used as internal vlan_id. The packet goes out
+    untagged.
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                assert (False)
+                return
+            ports      = config[ "port_map" ].keys( )
+            dst_ip_str = "224.0.0.1"
+            (
+                port_to_in_vlan,
+                port_to_out_vlan,
+                port_to_src_mac_str,
+                port_to_dst_mac_str,
+                port_to_src_ip,
+                port_to_src_ip_str,
+                Groups) = fill_mcast_pipeline_L3toL2(
+                self.controller,
+                logging,
+                ports,
+                is_ingress_tagged   = False,
+                is_egress_tagged    = False,
+                is_vlan_translated  = False,
+                is_max_vlan         = True
+                )
+
+            for in_port in ports:
+
+                parsed_pkt = simple_udp_packet(
+                    pktlen  = 96,
+                    eth_dst = port_to_dst_mac_str[in_port],
+                    eth_src = port_to_src_mac_str[in_port],
+                    ip_ttl  = 64,
+                    ip_src  = port_to_src_ip_str[in_port],
+                    ip_dst  = dst_ip_str
+                    )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                for out_port in ports:
+
+                    parsed_pkt = simple_udp_packet(
+                        pktlen  = 96,
+                        eth_dst = port_to_dst_mac_str[in_port],
+                        eth_src = port_to_src_mac_str[in_port],
+                        ip_ttl  = 64,
+                        ip_src  = port_to_src_ip_str[in_port],
+                        ip_dst  = dst_ip_str
+                        )
+                    pkt = str( parsed_pkt )
+                    if out_port == in_port:
+                        verify_no_packet( self, pkt, in_port )
+                        continue
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+class L3McastToL2UntagToTag( base_tests.SimpleDataPlane ):
+    """
+    Mcast routing, in this test case the traffic is untagged.
+    300 is used as vlan_id. The packet goes out
+    tagged.
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                assert (False)
+                return
+            ports      = config[ "port_map" ].keys( )
+            dst_ip_str = "224.0.0.1"
+            (
+                port_to_in_vlan,
+                port_to_out_vlan,
+                port_to_src_mac_str,
+                port_to_dst_mac_str,
+                port_to_src_ip,
+                port_to_src_ip_str,
+                Groups) = fill_mcast_pipeline_L3toL2(
+                self.controller,
+                logging,
+                ports,
+                is_ingress_tagged   = False,
+                is_egress_tagged    = True,
+                is_vlan_translated  = False,
+                is_max_vlan         = False
+                )
+
+            for in_port in ports:
+
+                parsed_pkt = simple_udp_packet(
+                    pktlen  = 96,
+                    eth_dst = port_to_dst_mac_str[in_port],
+                    eth_src = port_to_src_mac_str[in_port],
+                    ip_ttl  = 64,
+                    ip_src  = port_to_src_ip_str[in_port],
+                    ip_dst  = dst_ip_str
+                    )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                for out_port in ports:
+
+                    parsed_pkt = simple_udp_packet(
+                        pktlen          = 100,
+                        dl_vlan_enable  = True,
+                        vlan_vid        = port_to_out_vlan[in_port],
+                        eth_dst         = port_to_dst_mac_str[in_port],
+                        eth_src         = port_to_src_mac_str[in_port],
+                        ip_ttl          = 64,
+                        ip_src          = port_to_src_ip_str[in_port],
+                        ip_dst          = dst_ip_str
+                        )
+                    pkt = str( parsed_pkt )
+                    if out_port == in_port:
+                        verify_no_packet( self, pkt, in_port )
+                        continue
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+class L3McastToL2TagToUntag( base_tests.SimpleDataPlane ):
+    """
+    Mcast routing, in this test case the traffic is tagged.
+    300 is used as vlan_id. The packet goes out
+    untagged.
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                assert (False)
+                return
+            ports      = config[ "port_map" ].keys( )
+            dst_ip_str = "224.0.0.1"
+            (
+                port_to_in_vlan,
+                port_to_out_vlan,
+                port_to_src_mac_str,
+                port_to_dst_mac_str,
+                port_to_src_ip,
+                port_to_src_ip_str,
+                Groups) = fill_mcast_pipeline_L3toL2(
+                self.controller,
+                logging,
+                ports,
+                is_ingress_tagged   = True,
+                is_egress_tagged    = False,
+                is_vlan_translated  = False,
+                is_max_vlan         = False
+                )
+
+            for in_port in ports:
+
+                parsed_pkt = simple_udp_packet(
+                    pktlen         = 100,
+                    dl_vlan_enable = True,
+                    vlan_vid       = port_to_in_vlan[in_port],
+                    eth_dst        = port_to_dst_mac_str[in_port],
+                    eth_src        = port_to_src_mac_str[in_port],
+                    ip_ttl         = 64,
+                    ip_src         = port_to_src_ip_str[in_port],
+                    ip_dst         = dst_ip_str
+                    )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                for out_port in ports:
+
+                    parsed_pkt = simple_udp_packet(
+                        pktlen          = 96,
+                        eth_dst         = port_to_dst_mac_str[in_port],
+                        eth_src         = port_to_src_mac_str[in_port],
+                        ip_ttl          = 64,
+                        ip_src          = port_to_src_ip_str[in_port],
+                        ip_dst          = dst_ip_str
+                        )
+                    pkt = str( parsed_pkt )
+                    if out_port == in_port:
+                        verify_no_packet( self, pkt, in_port )
+                        continue
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+class L3McastToL2TagToTag( base_tests.SimpleDataPlane ):
+    """
+    Mcast routing, in this test case the traffic is tagged.
+    300 is used as vlan_id. The packet goes out tagged.
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                assert (False)
+                return
+            ports      = config[ "port_map" ].keys( )
+            dst_ip_str = "224.0.0.1"
+            (
+                port_to_in_vlan,
+                port_to_out_vlan,
+                port_to_src_mac_str,
+                port_to_dst_mac_str,
+                port_to_src_ip,
+                port_to_src_ip_str,
+                Groups) = fill_mcast_pipeline_L3toL2(
+                self.controller,
+                logging,
+                ports,
+                is_ingress_tagged   = True,
+                is_egress_tagged    = True,
+                is_vlan_translated  = False,
+                is_max_vlan         = False
+                )
+
+            for in_port in ports:
+
+                parsed_pkt = simple_udp_packet(
+                    pktlen         = 100,
+                    dl_vlan_enable = True,
+                    vlan_vid       = port_to_in_vlan[in_port],
+                    eth_dst        = port_to_dst_mac_str[in_port],
+                    eth_src        = port_to_src_mac_str[in_port],
+                    ip_ttl         = 64,
+                    ip_src         = port_to_src_ip_str[in_port],
+                    ip_dst         = dst_ip_str
+                    )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                for out_port in ports:
+
+                    parsed_pkt = simple_udp_packet(
+                        pktlen         = 100,
+                        dl_vlan_enable = True,
+                        vlan_vid       = port_to_in_vlan[in_port],
+                        eth_dst        = port_to_dst_mac_str[in_port],
+                        eth_src        = port_to_src_mac_str[in_port],
+                        ip_ttl         = 64,
+                        ip_src         = port_to_src_ip_str[in_port],
+                        ip_dst         = dst_ip_str
+                        )
+                    pkt = str( parsed_pkt )
+                    if out_port == in_port:
+                        verify_no_packet( self, pkt, in_port )
+                        continue
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+class L3McastToL2TagToTagTranslated( base_tests.SimpleDataPlane ):
+    """
+    Mcast routing, in this test case the traffic is tagged.
+    port+1 is used as ingress vlan_id. The packet goes out
+    tagged. 4094-port is used as egress vlan_id
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                assert (False)
+                return
+            ports      = config[ "port_map" ].keys( )
+            dst_ip_str = "224.0.0.1"
+            (
+                port_to_in_vlan,
+                port_to_out_vlan,
+                port_to_src_mac_str,
+                port_to_dst_mac_str,
+                port_to_src_ip,
+                port_to_src_ip_str,
+                Groups) = fill_mcast_pipeline_L3toL2(
+                self.controller,
+                logging,
+                ports,
+                is_ingress_tagged   = True,
+                is_egress_tagged    = True,
+                is_vlan_translated  = True,
+                is_max_vlan         = False
+                )
+
+            for in_port in ports:
+
+                parsed_pkt = simple_udp_packet(
+                    pktlen         = 100,
+                    dl_vlan_enable = True,
+                    vlan_vid       = port_to_in_vlan[in_port],
+                    eth_dst        = port_to_dst_mac_str[in_port],
+                    eth_src        = port_to_src_mac_str[in_port],
+                    ip_ttl         = 64,
+                    ip_src         = port_to_src_ip_str[in_port],
+                    ip_dst         = dst_ip_str
+                    )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                for out_port in ports:
+
+                    parsed_pkt = simple_udp_packet(
+                        pktlen         = 100,
+                        dl_vlan_enable = True,
+                        vlan_vid       = port_to_out_vlan[in_port],
+                        eth_dst        = port_to_dst_mac_str[in_port],
+                        eth_src        = port_to_src_mac_str[in_port],
+                        ip_ttl         = 64,
+                        ip_src         = port_to_src_ip_str[in_port],
+                        ip_dst         = dst_ip_str
+                        )
+                    pkt = str( parsed_pkt )
+                    if out_port == in_port:
+                        verify_no_packet( self, pkt, in_port )
+                        continue
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class L3McastTrafficThenDrop( base_tests.SimpleDataPlane ):
+    # fails on alternate repeated runs
+    """
+    Mcast routing, in this test case the traffic is untagged.
+    4094 is used as internal vlan_id. We first install aa full pipeline,
+    test that it forwards properly then remove all rules on table 40 and
+    mcast groups and ensure traffic is dropped. Blackhole of mcast traffic
+    if no tree is programmed on the switch.
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                assert (False)
+                return
+            ports      = config[ "port_map" ].keys( )
+            dst_ip_str = "224.0.0.1"
+            (
+                port_to_in_vlan,
+                port_to_out_vlan,
+                port_to_src_mac_str,
+                port_to_dst_mac_str,
+                port_to_src_ip,
+                port_to_src_ip_str,
+                Groups) = fill_mcast_pipeline_L3toL2(
+                self.controller,
+                logging,
+                ports,
+                is_ingress_tagged   = False,
+                is_egress_tagged    = False,
+                is_vlan_translated  = False,
+                is_max_vlan         = True
+                )
+
+            for in_port in ports:
+
+                parsed_pkt = simple_udp_packet(
+                    pktlen  = 96,
+                    eth_dst = port_to_dst_mac_str[in_port],
+                    eth_src = port_to_src_mac_str[in_port],
+                    ip_ttl  = 64,
+                    ip_src  = port_to_src_ip_str[in_port],
+                    ip_dst  = dst_ip_str
+                    )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                for out_port in ports:
+
+                    parsed_pkt = simple_udp_packet(
+                        pktlen  = 96,
+                        eth_dst = port_to_dst_mac_str[in_port],
+                        eth_src = port_to_src_mac_str[in_port],
+                        ip_ttl  = 64,
+                        ip_src  = port_to_src_ip_str[in_port],
+                        ip_dst  = dst_ip_str
+                        )
+                    pkt = str( parsed_pkt )
+                    if out_port == in_port:
+                        verify_no_packet( self, pkt, in_port )
+                        continue
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+
+            delete_all_flows_one_table(ctrl=self.controller, logger=logging, table_id=40);
+            delete_all_groups(self.controller)
+
+            for in_port in ports:
+
+                parsed_pkt = simple_udp_packet(
+                    pktlen  = 96,
+                    eth_dst = port_to_dst_mac_str[in_port],
+                    eth_src = port_to_src_mac_str[in_port],
+                    ip_ttl  = 64,
+                    ip_src  = port_to_src_ip_str[in_port],
+                    ip_dst  = dst_ip_str
+                    )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                for out_port in ports:
+
+                    parsed_pkt = simple_udp_packet(
+                        pktlen  = 96,
+                        eth_dst = port_to_dst_mac_str[in_port],
+                        eth_src = port_to_src_mac_str[in_port],
+                        ip_ttl  = 64,
+                        ip_src  = port_to_src_ip_str[in_port],
+                        ip_dst  = dst_ip_str
+                        )
+                    pkt = str( parsed_pkt )
+                    if out_port == in_port:
+                        verify_no_packet( self, pkt, in_port )
+                        continue
+                    verify_no_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class _MplsFwd( base_tests.SimpleDataPlane ):
+    """ Verify basic MPLS forwarding: Label switch router  """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+            dip = 0xc0a80001
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            # Assigns unique hardcoded test_id to make sure tests don't overlap when writing rules
+            ports = config[ "port_map" ].keys( )
+            for port in ports:
+                # Shift MPLS label and VLAN ID by 16 to avoid reserved values
+                vlan_id = port + 16
+                mpls_label = port + 16
+
+                # add l2 interface group
+                id = port
+                l2_gid, l2_msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, False )
+                dst_mac[ 5 ] = port
+                mpls_gid, mpls_msg = add_mpls_intf_group( self.controller, l2_gid, dst_mac, intf_src_mac,
+                        vlan_id, id )
+                mpls_label_gid, mpls_label_msg = add_mpls_label_group( self.controller,
+                        subtype=OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL, index=id, ref_gid=mpls_gid,
+                        push_mpls_header=False, set_mpls_label=mpls_label, set_bos=1 )
+                #ecmp_gid, ecmp_msg = add_mpls_forwarding_group( self.controller,
+                #        subtype=OFDPA_MPLS_GROUP_SUBTYPE_ECMP, index=id, ref_gids=[mpls_label_gid] )
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x8847, intf_src_mac, vlan_id, goto_table=24 )
+                else:
+                    add_termination_flow( self.controller, port, 0x8847, intf_src_mac, vlan_id, goto_table=24 )
+                #add_mpls_flow( self.controller, ecmp_gid, port, goto_table=29 )
+                if config["switch_type"] != 'xpliant':
+                    add_mpls_flow( self.controller, mpls_label_gid, mpls_label, goto_table=29 )
+                else:
+                    xpliant_add_mpls_flow( self.controller, mpls_label_gid, mpls_label, goto_table=29 )
+                dst_ip = dip + (vlan_id << 8)
+                Groups._put( l2_gid )
+                Groups._put( mpls_gid )
+                Groups._put( mpls_label_gid )
+                #Groups._put( ecmp_gid )
+            do_barrier( self.controller )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            for in_port in ports:
+                ip_src = '192.168.%02d.1' % (in_port)
+                for out_port in ports:
+                    if in_port == out_port:
+                        continue
+
+                    # Shift MPLS label and VLAN ID by 16 to avoid reserved values
+                    out_mpls_label = out_port + 16
+                    in_vlan_vid = in_port + 16
+                    out_vlan_vid = out_port + 16
+
+                    ip_dst = '192.168.%02d.1' % (out_port)
+                    label = (out_mpls_label, 0, 1, 32)
+                    parsed_pkt = mpls_packet( pktlen=104, dl_vlan_enable=True, vlan_vid=(in_vlan_vid),
+                            ip_src=ip_src, ip_dst=ip_dst, eth_dst=switch_mac, label=[ label ] )
+                    pkt = str( parsed_pkt )
+                    self.dataplane.send( in_port, pkt )
+
+                    # build expect packet
+                    mac_dst = '00:00:00:22:22:%02X' % (out_port)
+                    label = (out_mpls_label, 0, 1, 31)
+                    exp_pkt = mpls_packet( pktlen=104, dl_vlan_enable=True, vlan_vid=(out_vlan_vid),
+                            ip_src=ip_src, ip_dst=ip_dst, eth_src=switch_mac, eth_dst=mac_dst,
+                            label=[ label ] )
+                    pkt = str( exp_pkt )
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class _MplsTermination( base_tests.SimpleDataPlane ):
+    """ Verify MPLS VPN Termination at penultimate hop """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+            dip = 0xc0a80001
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            # Assigns unique hardcoded test_id to make sure tests don't overlap when writing rules
+            ports = config[ "port_map" ].keys( )
+            for port in ports:
+                # Shift MPLS label and VLAN ID by 16 to avoid reserved values
+                vlan_id = port + 16
+                mpls_label = port + 16
+
+                # add l2 interface group
+                id, dst_mac[ 5 ] = port, port
+                l2_gid, l2_msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, False )
+                # add L3 Unicast  group
+                l3_msg = add_l3_unicast_group( self.controller, port, vlanid=vlan_id, id=id,
+                        src_mac=intf_src_mac, dst_mac=dst_mac )
+                # add L3 ecmp group
+                ecmp_msg = add_l3_ecmp_group( self.controller, id, [ l3_msg.group_id ] )
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x8847, intf_src_mac, vlan_id, goto_table=24 )
+                else:
+                    add_termination_flow( self.controller, port, 0x8847, intf_src_mac, vlan_id, goto_table=24 )
+
+                if config["switch_type"] != 'xpliant':
+                    add_mpls_flow( self.controller, ecmp_msg.group_id, mpls_label )
+                else:
+                    xpliant_add_mpls_flow( self.controller, ecmp_msg.group_id, mpls_label )
+
+                # add_mpls_flow(self.controller, label=port)
+                dst_ip = dip + (vlan_id << 8)
+                # add_unicast_routing_flow(self.controller, 0x0800, dst_ip, 0xffffff00,
+                #                         ecmp_msg.group_id, 1)
+                Groups._put( l2_gid )
+                Groups._put( l3_msg.group_id )
+                Groups._put( ecmp_msg.group_id )
+            do_barrier( self.controller )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            for in_port in ports:
+                ip_src = '192.168.%02d.1' % (in_port)
+                for out_port in ports:
+                    if in_port == out_port:
+                        continue
+
+                    # Shift MPLS label and VLAN ID by 16 to avoid reserved values
+                    out_mpls_label = out_port + 16
+                    in_vlan_vid = in_port + 16
+                    out_vlan_vid = out_port + 16
+
+                    ip_dst = '192.168.%02d.1' % (out_port)
+                    label = (out_mpls_label, 0, 1, 32)
+                    parsed_pkt = mpls_packet( pktlen=104, dl_vlan_enable=True, vlan_vid=(in_vlan_vid),
+                            ip_src=ip_src, ip_dst=ip_dst, eth_dst=switch_mac, label=[ label ] )
+                    pkt = str( parsed_pkt )
+                    self.dataplane.send( in_port, pkt )
+                    # build expect packet
+                    mac_dst = '00:00:00:22:22:%02X' % (out_port)
+                    if config["switch_type"] != 'xpliant':
+                        ip_ttl=31
+                    else:
+                        ip_ttl=64
+                    exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=(out_vlan_vid),
+                            eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=ip_ttl, ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( exp_pkt )
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+@disabled
+class One_MplsTermination( base_tests.SimpleDataPlane ):
+    """
+    Verify MPLS VPN Termination at penultimate hop in only one direction
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+            dip = 0xc0a80001
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            # Assigns unique hardcoded test_id to make sure tests don't overlap when writing rules
+            ports = config[ "port_map" ].keys( )
+            inport = ports[0]
+            outport = ports[1]
+
+            # Shift MPLS label and VLAN ID by 16 to avoid reserved values
+            invlan_id = inport + 16
+            outvlan_id = outport + 16
+            mpls_label = outport + 16
+
+            # add l2 interface group
+            id, dst_mac[ 5 ] = inport, outport
+            l2_gid, l2_msg = add_one_l2_interface_group( self.controller, outport, outvlan_id, True, False )
+            # add L3 Unicast  group
+            l3_msg = add_l3_unicast_group( self.controller, outport, vlanid=outvlan_id, id=id,
+                                           src_mac=intf_src_mac, dst_mac=dst_mac )
+            # add L3 ecmp group
+            ecmp_msg = add_l3_ecmp_group( self.controller, id, [ l3_msg.group_id ] )
+            # add vlan flow table
+            add_one_vlan_table_flow( self.controller, inport, 1, invlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+            # add tmac flow
+            if config["switch_type"] == "qmx":
+                add_termination_flow( self.controller, 0, 0x8847, intf_src_mac, invlan_id, goto_table=24 )
+            else:
+                add_termination_flow( self.controller, inport, 0x8847, intf_src_mac, invlan_id, goto_table=24 )
+            # add mpls termination flow
+            add_mpls_flow( self.controller, ecmp_msg.group_id, mpls_label, send_barrier=True )
+            Groups._put( l2_gid )
+            Groups._put( l3_msg.group_id )
+            Groups._put( ecmp_msg.group_id )
+
+            time.sleep(0.1)
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            ip_src = '192.168.%02d.1' % (inport)
+            # Shift MPLS label and VLAN ID by 16 to avoid reserved values
+            out_mpls_label = outport + 16
+            in_vlan_vid = inport + 16
+            out_vlan_vid = outport + 16
+
+            ip_dst = '192.168.%02d.1' % (outport)
+            label = (out_mpls_label, 0, 1, 32)
+            parsed_pkt = mpls_packet( pktlen=104, dl_vlan_enable=True, vlan_vid=(in_vlan_vid),
+                                      ip_src=ip_src, ip_dst=ip_dst, eth_dst=switch_mac, label=[ label ] )
+            pkt = str( parsed_pkt )
+            self.dataplane.send( inport, pkt )
+            # build expect packet
+            mac_dst = '00:00:00:22:22:%02X' % (outport)
+            exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=(out_vlan_vid),
+                                         eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=31, ip_src=ip_src, ip_dst=ip_dst )
+            pkt = str( exp_pkt )
+            verify_packet( self, pkt, outport )
+            verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+class FabricSW_OF__24UcastTagged_TC_0045( base_tests.SimpleDataPlane ):
+    """ Verify /24 IP forwarding to L3 Interface """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            test_id = 26
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            ports = config[ "port_map" ].keys( )
+            for port in ports:
+                # add l2 interface group
+                vlan_id = port + test_id
+                l2gid, msg = add_one_l2_interface_group( self.controller, port, vlan_id=vlan_id,
+                        is_tagged=True, send_barrier=False )
+                dst_mac[ 5 ] = vlan_id
+                l3_msg = add_l3_unicast_group( self.controller, port, vlanid=vlan_id, id=vlan_id,
+                        src_mac=intf_src_mac, dst_mac=dst_mac )
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                # add unicast routing flow
+                dst_ip = dip + (vlan_id << 8)
+                # def add_unicast_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_ctrl=False, send_barrier=False, priority = 1):
+                add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffff00, l3_msg.group_id )
+                Groups.put( l2gid )
+                Groups.put( l3_msg.group_id )
+            do_barrier( self.controller )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            for in_port in ports:
+                mac_src = '00:00:00:22:22:%02X' % (test_id + in_port)
+                ip_src = '192.168.%02d.1' % (test_id + in_port)
+                for out_port in ports:
+                    if in_port == out_port:
+                        continue
+                    ip_dst = '192.168.%02d.1' % (test_id + out_port)
+                    parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True,
+                            vlan_vid=(test_id + in_port), eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64,
+                            ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( parsed_pkt )
+                    self.dataplane.send( in_port, pkt )
+                    # build expected packet
+                    mac_dst = '00:00:00:22:22:%02X' % (test_id + out_port)
+                    exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True,
+                            vlan_vid=(test_id + out_port), eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=63,
+                            ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( exp_pkt )
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+class _24UcastRouteBlackHole( base_tests.SimpleDataPlane ):
+    """ Verify black-holing of unicast routes, feature present only from OFDPA Premium 1.1.3.0"""
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            test_id = 27
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            ports = config[ "port_map" ].keys( )
+            for port in ports:
+                # add l2 interface group
+                vlan_id = port + test_id
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                # add unicast routing flow
+                #dst ip = 10.0.0.0/8
+                dst_ip = 0x0a000000
+                add_unicast_blackhole_flow(self.controller, 0x0800, dst_ip, 0xffffff00 )
+            do_barrier( self.controller )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            for in_port in ports:
+                mac_src = '00:00:00:22:22:%02X' % (test_id + in_port)
+                ip_src = '192.168.%02d.1' % (test_id + in_port)
+                for out_port in ports:
+                    if in_port == out_port:
+                        continue
+                    ip_dst = '192.168.%02d.1' % (test_id + out_port)
+                    parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True,
+                            vlan_vid=(test_id + in_port), eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64,
+                            ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( parsed_pkt )
+                    self.dataplane.send( in_port, pkt )
+                    # build expected packet
+                    mac_dst = '00:00:00:22:22:%02X' % (test_id + out_port)
+                    exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True,
+                            vlan_vid=(test_id + out_port), eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=63,
+                            ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( exp_pkt )
+                    verify_no_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+class _0Ucast( base_tests.SimpleDataPlane ):
+    """  Verify default gateway IP forwarding to L3 Interface ( /0 rule ) """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            ports = config[ "port_map" ].keys( )
+            for port in ports:
+                # add l2 interface group
+                vlan_id = port
+                l2gid, msg = add_one_l2_interface_group( self.controller, port, vlan_id=vlan_id + 1,
+                        is_tagged=True, send_barrier=False )
+                dst_mac[ 5 ] = vlan_id
+                l3_msg = add_l3_unicast_group( self.controller, port, vlanid=vlan_id + 1, id=vlan_id,
+                        src_mac=intf_src_mac, dst_mac=dst_mac )
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                # add unicast routing flow
+                dst_ip = dip + (vlan_id << 8)
+                add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, l3_msg.group_id, priority=2 )
+                Groups.put( l2gid )
+                Groups.put( l3_msg.group_id )
+            l3_gid = encode_l3_unicast_group_id( ports[ 0 ] )
+            dst_ip = 0x0
+            add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0x0, l3_gid )
+            do_barrier( self.controller )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            for in_port in ports:
+                mac_src = '00:00:00:22:22:%02X' % (in_port)
+                ip_src = '192.168.%02d.1' % (in_port)
+                for out_port in ports:
+                    if in_port == out_port:
+                        continue
+                    ip_dst = '192.168.%02d.1' % (out_port)
+                    parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=(in_port),
+                            eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( parsed_pkt )
+                    self.dataplane.send( in_port, pkt )
+                    # build expected packet
+                    mac_dst = '00:00:00:22:22:%02X' % (out_port)
+                    exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=(out_port + 1),
+                            eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=63, ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( exp_pkt )
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+                    ip_dst = '1.168.%02d.1' % ports[ 0 ]
+                    parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=in_port,
+                            eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+                    pkt = str( parsed_pkt )
+                    self.dataplane.send( in_port, pkt )
+                    # build expect packet
+                    mac_dst = '00:00:00:22:22:%02X' % ports[ 0 ]
+                    exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=ports[ 0 ] + 1,
+                            ip_ttl=63, ip_src=ip_src, ip_dst=ip_dst, eth_dst=mac_dst, eth_src=switch_mac )
+                    pkt = str( exp_pkt )
+                    verify_packet( self, pkt, ports[ 0 ] )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+class Unfiltered( base_tests.SimpleDataPlane ):
+    """
+    Attempt to add an unfiltered group: [ATTENTION] this doesn't verify addition
+    """
+
+    def runTest( self ):
+        try:
+            ports = sorted( config[ "port_map" ].keys( ) )
+            vlan_id = 1;
+            for port in ports:
+                add_l2_unfiltered_group( self.controller, [ port ], False )
+            do_barrier( self.controller )
+        finally:
+            delete_all_flows( self.controller )
+            delete_all_groups( self.controller )
+
+@disabled
+class L3McastToVPN( base_tests.SimpleDataPlane ):
+    """
+    Mcast routing and VPN initiation
+    """
+
+    def runTest( self ):
+        """
+        port1 (vlan 1)-> port 2 (vlan 2)
+        """
+        try:
+            delete_all_flows( self.controller )
+            delete_all_groups( self.controller )
+
+            if len( config[ "port_map" ] ) < 3:
+                logging.info( "Port count less than 3, can't run this case" )
+                assert (False)
+                return
+
+            vlan_id = 1
+            port2_out_vlan = 2
+            port3_out_vlan = 3
+            in_vlan = 1  # macast group vid shall use input vlan diffe from l3 interface use output vlan
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            intf_src_mac_str = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            dst_mac = [ 0x01, 0x00, 0x5e, 0x01, 0x01, 0x01 ]
+            dst_mac_str = ':'.join( [ '%02X' % x for x in dst_mac ] )
+            port1_mac = [ 0x00, 0x11, 0x11, 0x11, 0x11, 0x11 ]
+            port1_mac_str = ':'.join( [ '%02X' % x for x in port1_mac ] )
+            src_ip = 0xc0a80101
+            src_ip_str = "192.168.1.1"
+            dst_ip = 0xe0010101
+            dst_ip_str = "224.1.1.1"
+
+            port1 = config[ "port_map" ].keys( )[ 0 ]
+            port2 = config[ "port_map" ].keys( )[ 1 ]
+            # port3=config["port_map"].keys()[2]
+
+            # add l2 interface group
+            for port in config[ "port_map" ].keys( ):
+                add_one_l2_interface_group( self.controller, port, vlan_id=vlan_id, is_tagged=False,
+                        send_barrier=False )
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                vlan_id += 1
+
+                # add termination flow
+            add_termination_flow( self.controller, port1, 0x0800, [ 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 ],
+                    vlan_id )
+
+            # add MPLS interface group
+            l2_gid = encode_l2_interface_group_id( port2_out_vlan, port2 )
+            mpls_gid2, mpls_msg = add_mpls_intf_group( self.controller, l2_gid, dst_mac, intf_src_mac,
+                    port2_out_vlan, port2 )
+            # l2_gid3 = encode_l2_interface_group_id(port3_out_vlan, port3)
+            # mpls_gid3, mpls_msg = add_mpls_intf_group(self.controller, l2_gid3, dst_mac, intf_src_mac, port3_out_vlan, port3)
+            # add L3VPN groups
+            mpls_label_gid2, mpls_label_msg = add_mpls_label_group( self.controller,
+                    subtype=OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL, index=(0x20000 + port2), ref_gid=mpls_gid2,
+                    push_mpls_header=True, set_mpls_label=port2, set_bos=1, cpy_ttl_outward=True )
+            # mpls_label_gid3, mpls_label_msg = add_mpls_label_group(self.controller, subtype=OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL,
+            #                                                       index=(0x10000+port3), ref_gid= mpls_gid3, push_mpls_header=True, set_mpls_label=port3, set_bos=1, cpy_ttl_outward=True)
+
+            mcat_group_msg = add_l3_mcast_group( self.controller, in_vlan, 2, [ mpls_label_gid2 ] )
+            add_mcast4_routing_flow( self.controller, in_vlan, src_ip, 0, dst_ip, mcat_group_msg.group_id )
+
+            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=1, eth_dst=dst_mac_str,
+                    eth_src=port1_mac_str, ip_ttl=64, ip_src=src_ip_str, ip_dst=dst_ip_str )
+            pkt = str( parsed_pkt )
+            self.dataplane.send( port1, pkt )
+            label = (12, 0, 1, 63)
+            exp_pkt = mpls_packet( pktlen=100, eth_dst=dst_mac_str, eth_src=intf_src_mac_str, ip_ttl=64,
+                    ip_src=src_ip_str, label=[ label ], ip_dst=dst_ip_str )
+            pkt = str( exp_pkt )
+            verify_packet( self, pkt, port2 )
+            # verify_packet(self, pkt, port3)
+            verify_no_other_packets( self )
+            delete_all_groups( self.controller )
+        finally:
+            delete_all_flows( self.controller )
+            delete_all_groups( self.controller )
+
+@disabled
+class PacketInSrcMacMiss( base_tests.SimpleDataPlane ):
+    """
+    Test packet in function on a src-mac miss
+    Send a packet to each dataplane port and verify that a packet
+    in message is received from the controller for each
+    #todo verify you stop receiving after adding rule
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            ports = sorted( config[ "port_map" ].keys( ) )
+
+            Groups = Queue.LifoQueue( )
+            for port in ports:
+                L2gid, l2msg = add_one_l2_interface_group( self.controller, port, 1, True, False )
+                add_one_vlan_table_flow( self.controller, port, 1, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                Groups.put( L2gid )
+            parsed_vlan_pkt = simple_tcp_packet( pktlen=104, vlan_vid=0x1001, dl_vlan_enable=True )
+            vlan_pkt = str( parsed_vlan_pkt )
+            for of_port in config[ "port_map" ].keys( ):
+                logging.info( "PacketInMiss test, port %d", of_port )
+                self.dataplane.send( of_port, vlan_pkt )
+                verify_packet_in( self, vlan_pkt, of_port, ofp.OFPR_NO_MATCH )
+                verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_all_groups( self.controller )
+
+
+class FabricSW_OF_EcmpGroupMod_TC_0025( base_tests.SimpleDataPlane ):
+    """
+        Verify referenced group can be modified by adding or removing buckets
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            # Hashes Test Name and uses it as id for installing unique groups
+            ports = config[ "port_map" ].keys( )
+            ecmp = [ ]
+            dst_ips = []
+            # add flows for all ports but include only the egress switchport (connected to ports[1])
+            # in the ecmp group
+            for port in ports:
+                vlan_id = port
+                id = port
+                # add l2 interface group
+                l2_gid, msg = add_one_l2_interface_group( self.controller, port, vlan_id=vlan_id,
+                        is_tagged=True, send_barrier=False )
+                dst_mac[ 5 ] = vlan_id
+                l3_msg = add_l3_unicast_group( self.controller, port, vlanid=vlan_id, id=id,
+                        src_mac=intf_src_mac, dst_mac=dst_mac )
+                if port == ports[1]:
+                    ecmp += [ l3_msg.group_id ]
+                Groups._put( l2_gid )
+                Groups._put( l3_msg.group_id )
+                ecmp_msg = add_l3_ecmp_group( self.controller, ports[ 0 ], [ l3_msg.group_id ] )
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                # add unicast routing flow
+                dst_ip = dip + (vlan_id << 8)
+                dst_ips += [dst_ip]
+                Groups._put( ecmp_msg.group_id )
+            mod_l3_ecmp_group( self.controller, ports[ 0 ], ecmp )
+            for dst_ip in dst_ips:
+                add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffff00, ecmp_msg.group_id )
+            do_barrier(self.controller)
+            time.sleep(0.1)
+            # first part of the test: send packet from ingress switchport and expect it at egress switchport
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            parsed_pkt = exp_pkt = 0
+            in_port = ports[0]
+            out_port = ports[1]
+            logging.info("\nSending packet to port: " + str(in_port) + ", expected egress on port: " + str(out_port))
+            mac_src = '00:00:00:22:22:%02X' % ports[ 0 ]
+            ip_src = '192.168.%02d.%02d' % (ports[ 0 ], 1)
+            ip_dst = '192.168.%02d.%02d' % (ports[ 1 ], 1)
+            tcp = out_port if out_port == 24 else 25
+            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=ports[ 0 ],
+                                            eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src,
+                                            ip_dst=ip_dst, tcp_dport=tcp )
+            pkt = str( parsed_pkt )
+            self.dataplane.send( ports[ 0 ], pkt )
+            # build expected packet at egress switchport
+            mac_dst = '00:00:00:22:22:%02X' % out_port
+            exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=out_port,
+                                         eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=63, ip_src=ip_src,
+                                         ip_dst=ip_dst, tcp_dport=tcp )
+            pkt = str( exp_pkt )
+            verify_packet( self, pkt, out_port )
+            verify_no_other_packets( self )
+
+            # second part of the test - edit the ecmp group to remove the orginal egress switchport
+            # and instead add the ingress switchport. Send packet from ingress switchport, and expect
+            # it back on the ingress switchport
+            l3_gid = encode_l3_unicast_group_id( ports[ 0 ] )
+            mod_l3_ecmp_group( self.controller, ports[ 0 ], [ l3_gid ] )
+            time.sleep(0.1)
+            logging.info("Sending packet to port: " + str(ports[0]) + ", expected egress on port: " + str(ports[0]))
+            mac_src = '00:00:00:22:22:%02X' % ports[ 0 ]
+            ip_src = '192.168.%02d.%02d' % (ports[ 0 ], 1)
+            ip_dst = '192.168.%02d.%02d' % (ports[ 1 ], 1)
+            tcp = port if port == 24 else 25
+            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=ports[ 0 ],
+                                            eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src,
+                                            ip_dst=ip_dst,tcp_dport=tcp )
+            pkt = str( parsed_pkt )
+            self.dataplane.send( ports[ 0 ], pkt )
+            # build expected packet
+            mac_dst = '00:00:00:22:22:%02X' % ports[ 0 ]
+            exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=ports[ 0 ],
+                                         eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=63, ip_src=ip_src,
+                                         ip_dst=ip_dst,tcp_dport=tcp )
+            # Expects packet on the input port
+            if config["switch_type"] != 'xpliant':
+                pkt = str( exp_pkt )
+                verify_packet( self, pkt, ports[ 0 ] )
+                verify_no_other_packets( self )
+
+            # third part of the test - edit the group to completely remove bucket. Packet sent
+            # should be dropped by the switch
+            mod_l3_ecmp_group( self.controller, ports[ 0 ], [ ] )
+            time.sleep(0.1)
+            logging.info("Sending packet to port: " + str(ports[0]) + ", expected drop")
+            mac_src = '00:00:00:22:22:%02X' % ports[ 0 ]
+            ip_src = '192.168.%02d.%02d' % (ports[ 0 ], 1)
+            ip_dst = '192.168.%02d.%02d' % (ports[ 1 ], 1)
+            tcp = port if port == 24 else 25
+            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=ports[ 0 ],
+                                            eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src,
+                                            ip_dst=ip_dst,tcp_dport=tcp )
+            pkt = str( parsed_pkt )
+            self.dataplane.send( ports[ 0 ], pkt )
+            verify_no_other_packets( self )
+
+            # final part of the test - edit the empty group to add back the bucket for the
+            # original egress port, and verify packet is received on egress switch port
+            l3_gid = encode_l3_unicast_group_id( ports[ 1 ] )
+            mod_l3_ecmp_group( self.controller, ports[ 0 ], [ l3_gid ] )
+            do_barrier(self.controller)
+            in_port = ports[0]
+            out_port = ports[1]
+            logging.info("Sending packet to port: " + str(in_port) + ", expected egress on port: " + str(out_port))
+            mac_src = '00:00:00:22:22:%02X' % ports[ 0 ]
+            ip_src = '192.168.%02d.%02d' % (ports[ 0 ], 1)
+            ip_dst = '192.168.%02d.%02d' % (ports[ 1 ], 1)
+            tcp = out_port if out_port == 24 else 25
+            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=ports[ 0 ],
+                                            eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src,
+                                            ip_dst=ip_dst, tcp_dport=tcp )
+            pkt = str( parsed_pkt )
+            self.dataplane.send( ports[ 0 ], pkt )
+            # build expected packet at egress switchport
+            mac_dst = '00:00:00:22:22:%02X' % out_port
+            exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=out_port,
+                                         eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=63, ip_src=ip_src,
+                                         ip_dst=ip_dst, tcp_dport=tcp )
+            pkt = str( exp_pkt )
+            verify_packet( self, pkt, out_port )
+            verify_no_other_packets( self )
+
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+class Untagged( base_tests.SimpleDataPlane ):
+    """
+        Verify VLAN filtering table does not require OFPVID_PRESENT bit to be 0.
+        This should be fixed in OFDPA 2.0 GA and above, the test fails with
+        previous versions of the OFDPA.
+
+        Two rules are necessary in VLAN table (10):
+        1) Assignment: match 0x0000/(no mask), set_vlan_vid 0x100A, goto 20
+        2) Filtering: match 0x100A/0x1FFF, goto 20
+
+        In this test case vlan_id = (MAX_INTERNAL_VLAN - port_no).
+        The remaining part of the test is based on the use of the bridging table
+    """
+
+    MAX_INTERNAL_VLAN = 4094
+
+    def runTest( self ):
+        groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            ports = sorted( config[ "port_map" ].keys( ) )
+            for port in ports:
+                vlan_id = Untagged.MAX_INTERNAL_VLAN - port
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+                add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_UNTAG )
+                for other_port in ports:
+                    if other_port == port:
+                        continue
+                    L2gid, l2msg = add_one_l2_interface_group( self.controller, other_port, vlan_id, False, False )
+                    groups.put( L2gid )
+                    add_bridge_flow( self.controller, [ 0x00, 0x12, 0x34, 0x56, 0x78, other_port ], vlan_id, L2gid, True )
+
+            do_barrier( self.controller )
+
+            for out_port in ports:
+                # change dest based on port number
+                mac_dst = '00:12:34:56:78:%02X' % out_port
+                for in_port in ports:
+                    if in_port == out_port:
+                        continue
+                    pkt = str( simple_tcp_packet( eth_dst=mac_dst ) )
+                    self.dataplane.send( in_port, pkt )
+                    for ofport in ports:
+                        if ofport in [ out_port ]:
+                            verify_packet( self, pkt, ofport )
+                        else:
+                            verify_no_packet( self, pkt, ofport )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, groups )
+            delete_all_groups( self.controller )
+
+class MPLSSwapTest( base_tests.SimpleDataPlane ):
+    """
+    MPLS switching with the same label used.
+    Used for interconnecting spines between different fabrics where
+    the label should not be popped, but swapepd with the same label.
+    """
+
+    def runTest( self ):
+        try:
+            delete_all_flows( self.controller )
+            delete_all_groups( self.controller )
+
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 3, can't run this case" )
+                assert (False)
+                return
+
+            input_src_mac = [ 0x00, 0x00, 0x5e, 0x01, 0x01, 0x01 ]
+            input_src_mac_str = ':'.join( [ '%02X' % x for x in input_src_mac ] )
+
+            input_dst_mac = [ 0x00, 0x00, 0x5e, 0x01, 0x01, 0x02 ]
+            input_dst_mac_str = ':'.join( [ '%02X' % x for x in input_dst_mac ] )
+
+            output_dst_mac = [ 0x00, 0x00, 0x5e, 0x01, 0x01, 0x03 ]
+            output_dst_mac_str = ':'.join( [ '%02X' % x for x in output_dst_mac ] )
+
+            mpls_label = 1000
+
+            src_ip = 0xc0a80101
+            src_ip_str = "192.168.1.1"
+            dst_ip = 0xe0010101
+            dst_ip_str = "224.1.1.1"
+
+            src_port = config[ "port_map" ].keys( )[ 0 ]
+            dst_port = config[ "port_map" ].keys( )[ 1 ]
+
+            out_vlan = 4094
+
+            add_one_l2_interface_group( self.controller, dst_port, vlan_id=out_vlan, is_tagged=False,
+                       		 	send_barrier=True )
+
+            # add vlan flow table
+            add_one_vlan_table_flow( self.controller, src_port, out_vlan_id=out_vlan, vlan_id=out_vlan, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+            add_one_vlan_table_flow( self.controller, src_port, out_vlan_id=out_vlan, vlan_id=out_vlan, flag=VLAN_TABLE_FLAG_ONLY_UNTAG )
+
+            # add termination flow
+
+            if config["switch_type"] == "qmx":
+                logging.debug("MPLSSwitching : Adding flow for qmx, without input port")
+                add_termination_flow( self.controller, 0, eth_type=0x08847, dst_mac=input_dst_mac, vlanid=out_vlan, goto_table=23)
+            else:
+                add_termination_flow( self.controller, in_port=src_port,
+				  eth_type=0x8847, dst_mac=input_dst_mac, vlanid=out_vlan, goto_table=23)
+
+	    # add groups that will be used now
+            l2_gid = encode_l2_interface_group_id( out_vlan, dst_port)
+            mpls_gid, mpls_msg = add_mpls_intf_group( self.controller, l2_gid,
+						      output_dst_mac, input_dst_mac,
+                    	  			      out_vlan, dst_port, send_barrier=True)
+            index = 60
+            mpls_swap_gid, mpls_swap_msg = add_mpls_swap_label_group( self.controller, mpls_gid,
+	 	            					      5, index, mpls_label)
+
+            # add flow to mpls table
+            add_mpls_flow_swap( self.controller, mpls_swap_gid, mpls_label, 0x8847, 1, send_barrier=True)
+
+            # we generate the packet which carries a single label
+            label = (mpls_label, 0, 1, 63)
+            parsed_pkt = mpls_packet(
+                pktlen=104,
+                label=[label],
+                eth_src=input_src_mac_str,
+                eth_dst=input_dst_mac_str,
+                )
+            pkt = str( parsed_pkt )
+
+            self.dataplane.send( src_port, pkt )
+
+            label = (mpls_label, 0, 1, 62)
+            parsed_pkt = mpls_packet(
+                pktlen=104,
+                label=[label],
+                eth_src=input_dst_mac_str,
+                eth_dst=output_dst_mac_str,
+                )
+            pkt = str( parsed_pkt )
+
+            verify_packet( self, pkt, dst_port )
+            verify_no_packet( self, pkt, src_port )
+            verify_no_other_packets( self )
+
+            delete_all_flows( self.controller )
+            delete_all_groups( self.controller )
+
+        finally:
+            delete_all_flows( self.controller )
+            delete_all_groups( self.controller )
+
+@disabled
+class DoubleToUntagged( base_tests.SimpleDataPlane ):
+    """
+         Verify MPLS IP VPN Initiation from /24 rule using ECMP
+         where we receive double tagged packets and output untagged
+         packets.
+
+         Each double tagged packet represents a subscriber where Outer tag is pon
+         and inner tag is the subrscriber tag.
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            input_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            input_src_mac_str = ':'.join( [ '%02X' % x for x in input_src_mac ] )
+
+            input_dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            input_dst_mac_str = ':'.join( [ '%02X' % x for x in input_dst_mac ] )
+
+            output_dst_mac = [ 0x00, 0x00, 0x00, 0x33, 0x33, 0x00 ]
+            output_dst_mac_str = ':'.join( [ '%02X' % x for x in output_dst_mac ] )
+
+            dip = 0xc0a80001
+            ports = config[ "port_map" ].keys( )
+
+            inner_vlan = 66
+            outer_vlan = 77
+            id = 10
+            mpls_label = 152
+
+            port = ports[0]
+            out_port = ports[1]
+
+            # add l2 interface group
+            l2_gid, l2_msg = add_one_l2_interface_group( self.controller, out_port, inner_vlan, False, True )
+
+            # add MPLS interface group
+            mpls_gid, mpls_msg = add_mpls_intf_group( self.controller, l2_gid, output_dst_mac, input_dst_mac,
+                    inner_vlan, id )
+
+            # add MPLS L3 VPN group
+            mpls_label_gid, mpls_label_msg = add_mpls_label_group( self.controller,
+                    subtype=OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL, index=id, ref_gid=mpls_gid,
+                    push_mpls_header=True, set_mpls_label=mpls_label, set_bos=1, set_ttl=32 )
+            ecmp_msg = add_l3_ecmp_group( self.controller, id, [ mpls_label_gid ] )
+
+            do_barrier( self.controller )
+
+            # add vlan flow table
+            add_one_vlan_table_flow( self.controller, port, 1, outer_vlan, vrf=0,
+                    flag=VLAN_TABLE_FLAG_ONLY_STACKED )
+
+            add_one_vlan_1_table_flow( self.controller, port, outer_vlan_id=outer_vlan, inner_vlan_id=inner_vlan,
+                    flag=VLAN_TABLE_FLAG_ONLY_UNTAG )
+
+            # add termination flow
+            if config["switch_type"] == "qmx":
+                add_termination_flow( self.controller, 0, 0x0800, input_dst_mac, inner_vlan )
+            else:
+                add_termination_flow( self.controller, port, 0x0800, input_dst_mac, inner_vlan )
+
+            # add_unicast_routing_flow(self.controller, 0x0800, dst_ip, 0, mpls_label_gid, vrf=2)
+            add_unicast_routing_flow( self.controller, 0x0800, dip, 0xffffff00, ecmp_msg.group_id,
+                    vrf=0 )
+            Groups._put( l2_gid )
+            Groups._put( mpls_gid )
+            Groups._put( mpls_label_gid )
+            Groups._put( ecmp_msg.group_id )
+
+            do_barrier( self.controller )
+
+            ip_src = '192.168.5.5'
+            ip_dst = '192.168.0.5'
+            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=inner_vlan, outer_vlan=outer_vlan,
+                    eth_dst=input_dst_mac_str, eth_src=input_src_mac_str, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+            pkt = str( parsed_pkt )
+
+            # print("Expected %s" % format_packet(pkt))
+
+            self.dataplane.send( port, pkt )
+
+            # build expect packet
+            label = (mpls_label, 0, 1, 32)
+            exp_pkt = mpls_packet( pktlen=96, dl_vlan_enable=False, ip_ttl=63,
+                    ip_src=ip_src, ip_dst=ip_dst, eth_dst=output_dst_mac_str, eth_src=input_dst_mac_str,
+                    label=[ label ] )
+            pkt = str( exp_pkt )
+            verify_packet( self, pkt, out_port )
+            verify_no_other_packets( self )
+
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class DoubleToUntaggedMultipleSubscribers( base_tests.SimpleDataPlane ):
+    """
+         Verify MPLS IP VPN Initiation from /24 rule using ECMP
+         where we receive double tagged packets and output untagged
+         packets.
+
+         Each double tagged packet represents a subscriber where Outer tag is pon
+         and inner tag is the subrscriber tag.
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            # each entry represents a subscriber [id, ip in hex, inner_vlan, outer_vlan, ip in dot form]
+            subscriber_info = [ [10, 0xc0a80001, 10, 100, "192.168.0.1"],
+                                [20, 0xc0a80002, 10, 101, "192.168.0.2"],
+                                [30, 0xc0a80003, 11, 100, "192.168.0.3"],
+                                [40, 0xc0a80004, 11, 101, "192.168.0.4"]]
+
+            print("")
+
+            for sub_info in subscriber_info:
+
+                print("Initializing rules for subscriber with id {0}".format(sub_info[0]))
+
+                input_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, sub_info[0] ]
+                input_src_mac_str = ':'.join( [ '%02X' % x for x in input_src_mac ] )
+
+                input_dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+                input_dst_mac_str = ':'.join( [ '%02X' % x for x in input_dst_mac ] )
+
+                output_dst_mac = [ 0x00, 0x00, 0x00, 0x33, 0x33, 0x00 ]
+                output_dst_mac_str = ':'.join( [ '%02X' % x for x in output_dst_mac ] )
+
+                dip = sub_info[1]
+                ports = config[ "port_map" ].keys( )
+
+                inner_vlan = sub_info[2]
+                outer_vlan = sub_info[3]
+                id = 10
+                mpls_label = 152
+
+                port = ports[0]
+                out_port = ports[1]
+
+                # add l2 interface group
+                l2_gid, l2_msg = add_one_l2_interface_group( self.controller, out_port, inner_vlan, False, True )
+
+                # add MPLS interface group
+                mpls_gid, mpls_msg = add_mpls_intf_group( self.controller, l2_gid, output_dst_mac, input_dst_mac,
+                        inner_vlan, id )
+
+                # add MPLS L3 VPN group
+                mpls_label_gid, mpls_label_msg = add_mpls_label_group( self.controller,
+                        subtype=OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL, index=id, ref_gid=mpls_gid,
+                        push_mpls_header=True, set_mpls_label=mpls_label, set_bos=1, set_ttl=32 )
+                ecmp_msg = add_l3_ecmp_group( self.controller, id, [ mpls_label_gid ] )
+
+                do_barrier( self.controller )
+
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, outer_vlan, vrf=0,
+                        flag=VLAN_TABLE_FLAG_ONLY_STACKED )
+
+                add_one_vlan_1_table_flow( self.controller, port, outer_vlan_id=outer_vlan, inner_vlan_id=inner_vlan,
+                        flag=VLAN_TABLE_FLAG_ONLY_UNTAG )
+
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, input_dst_mac, inner_vlan )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, input_dst_mac, inner_vlan )
+
+                # add_unicast_routing_flow(self.controller, 0x0800, dst_ip, 0, mpls_label_gid, vrf=2)
+                add_unicast_routing_flow( self.controller, 0x0800, dip, 0xffffff00, ecmp_msg.group_id,
+                        vrf=0 )
+                Groups._put( l2_gid )
+                Groups._put( mpls_gid )
+                Groups._put( mpls_label_gid )
+                Groups._put( ecmp_msg.group_id )
+
+                do_barrier( self.controller )
+
+            for sub_info in subscriber_info:
+
+                print("Sending packet for subscriber with id {0}".format(sub_info[0]))
+
+                input_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, sub_info[0] ]
+                input_src_mac_str = ':'.join( [ '%02X' % x for x in input_src_mac ] )
+
+                input_dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+                input_dst_mac_str = ':'.join( [ '%02X' % x for x in input_dst_mac ] )
+
+                output_dst_mac = [ 0x00, 0x00, 0x00, 0x33, 0x33, 0x00 ]
+                output_dst_mac_str = ':'.join( [ '%02X' % x for x in output_dst_mac ] )
+
+                dip = sub_info[1]
+                ports = config[ "port_map" ].keys( )
+
+                inner_vlan = sub_info[2]
+                outer_vlan = sub_info[3]
+                id = 10
+                mpls_label = 152
+
+                port = ports[0]
+                out_port = ports[1]
+
+                ip_src = sub_info[4]
+                ip_dst = '192.168.0.{}'.format(sub_info[0])
+                parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=inner_vlan, outer_vlan=outer_vlan,
+                        eth_dst=input_dst_mac_str, eth_src=input_src_mac_str, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+                pkt = str( parsed_pkt )
+
+                # print("Sent %s" % format_packet(pkt))
+
+                self.dataplane.send( port, pkt )
+
+                # build expect packet
+                label = (mpls_label, 0, 1, 32)
+                exp_pkt = mpls_packet( pktlen=96, dl_vlan_enable=False, ip_ttl=63,
+                        ip_src=ip_src, ip_dst=ip_dst, eth_dst=output_dst_mac_str, eth_src=input_dst_mac_str,
+                        label=[ label ] )
+                pkt = str( exp_pkt )
+                verify_packet( self, pkt, out_port )
+                verify_no_other_packets( self )
+
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+@disabled
+class UntaggedToDouble ( base_tests.SimpleDataPlane ):
+    """
+        Verify google senario where we need to go from
+        an untagged packet to a double tagged packet.
+
+        This is used for a single subscriber.
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            input_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            input_src_mac_str = ':'.join( [ '%02X' % x for x in input_src_mac ] )
+
+            input_dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            input_dst_mac_str = ':'.join( [ '%02X' % x for x in input_dst_mac ] )
+
+            output_dst_mac = [ 0x00, 0x00, 0x00, 0x33, 0x33, 0x00 ]
+            output_dst_mac_str = ':'.join( [ '%02X' % x for x in output_dst_mac ] )
+
+            dip = 0xc0a80001
+            ports = config[ "port_map" ].keys( )
+
+            inner_vlan = 66
+            outer_vlan = 77
+            id = 10
+            mpls_label = 152
+
+            port = ports[0]
+            out_port = ports[1]
+
+            # add l2 unfiltered interface group
+            l2_gid, l2_msg = add_one_l2_unfiltered_group( self.controller, out_port, True)
+
+            l3_msg = add_l3_unicast_group( self.controller, out_port, vlanid=4094, id=id,
+                        src_mac=input_dst_mac, dst_mac=output_dst_mac, gid=l2_gid)
+
+            do_barrier( self.controller )
+
+            # add vlan flow table
+            add_one_vlan_table_flow( self.controller, port, 1, 4094,
+                    flag=VLAN_TABLE_FLAG_ONLY_BOTH )
+
+            # add termination flow
+            if config["switch_type"] == "qmx":
+                add_termination_flow( self.controller, 0, 0x0800, input_dst_mac, 4094 )
+            else:
+                add_termination_flow( self.controller, port, 0x0800, input_dst_mac, 4094 )
+
+            add_unicast_routing_flow( self.controller, 0x0800, dip, 0xffffffff, l3_msg.group_id,
+                    vrf=0 )
+
+            add_one_egress_vlan_table_flow( self.controller, out_port, 4094 , inner_vlan, outer_vlan)
+
+            Groups._put( l2_gid )
+            Groups._put( l3_msg.group_id )
+
+            do_barrier( self.controller )
+
+            ip_src = '192.168.5.5'
+            ip_dst = '192.168.0.1'
+            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=False,
+                    eth_dst=input_dst_mac_str, eth_src=input_src_mac_str, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+            pkt = str( parsed_pkt )
+
+            # print("Input Packet %s" % format_packet(pkt))
+
+            self.dataplane.send( port, pkt )
+
+            # build expect packet
+            exp_pkt = simple_tcp_packet( pktlen=108, dl_vlan_enable=True, vlan_vid=inner_vlan, outer_vlan=outer_vlan,
+                    eth_dst=output_dst_mac_str, eth_src=input_dst_mac_str, ip_ttl=63, ip_src=ip_src, ip_dst=ip_dst )
+            pkt = str( exp_pkt )
+
+            # print("Expected Packet %s" % format_packet(pkt))
+
+            verify_packet( self, pkt, out_port )
+            verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class UntaggedToDoubleMultipleSubscribers ( base_tests.SimpleDataPlane ):
+    """
+        Verify google senario where we need to go from
+        an untagged packet to a double tagged packet.
+
+        This is used for multiple subscribers.
+
+        However, this solution does not scale, since we assign an internal vlan to each subscriber
+        used in L3 Unicast Group in order to differentiate between them in the Egress Vlan Table.
+    """
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            # each entry represents a subscriber [id, ip in hex, inner_vlan, outer_vlan, ip in dot form, internal vlan]
+            subscriber_info = [[1, 0xc0a80001, 10, 100, "192.168.0.1", 4000],
+                               [2, 0xc0a80002, 10, 101, "192.168.0.2", 4001],
+                               [3, 0xc0a80003, 11, 100, "192.168.0.3", 4002],
+                               [4, 0xc0a80004, 11, 101, "192.168.0.4", 4003]]
+
+            print("")
+
+            for sub_info in subscriber_info:
+
+                print("Initializing rules for subscriber with id {0}".format(sub_info[0]))
+
+                input_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, sub_info[0] ]
+                input_src_mac_str = ':'.join( [ '%02X' % x for x in input_src_mac ] )
+
+                input_dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+                input_dst_mac_str = ':'.join( [ '%02X' % x for x in input_dst_mac ] )
+
+                output_dst_mac = [ 0x00, 0x00, 0x00, 0x33, 0x33, 0x00 ]
+                output_dst_mac_str = ':'.join( [ '%02X' % x for x in output_dst_mac ] )
+
+                dip = sub_info[1]
+                ports = config[ "port_map" ].keys( )
+
+                inner_vlan = sub_info[2]
+                outer_vlan = sub_info[3]
+                internal_vlan = sub_info[5]
+                id = sub_info[0] + 10
+
+                port = ports[0]
+                out_port = ports[1]
+
+                # add l2 unfiltered interface group
+                l2_gid, l2_msg = add_one_l2_unfiltered_group( self.controller, out_port, True)
+
+                l3_msg = add_l3_unicast_group( self.controller, out_port, vlanid=internal_vlan, id=id,
+                            src_mac=input_dst_mac, dst_mac=output_dst_mac, gid=l2_gid)
+
+                do_barrier( self.controller )
+
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, 1, 4094,
+                        flag=VLAN_TABLE_FLAG_ONLY_BOTH )
+
+                # add termination flow
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, input_dst_mac, 4094 )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, input_dst_mac, 4094 )
+
+                add_unicast_routing_flow( self.controller, 0x0800, dip, 0xffffffff, l3_msg.group_id,
+                        vrf=0 )
+
+                add_one_egress_vlan_table_flow( self.controller, out_port, internal_vlan, inner_vlan, outer_vlan)
+
+                Groups._put( l2_gid )
+                Groups._put( l3_msg.group_id )
+                do_barrier( self.controller )
+
+            for sub_info in subscriber_info:
+
+                print("Sending packet for subscriber with id {0}".format(sub_info[0]))
+
+                input_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, sub_info[0] ]
+                input_src_mac_str = ':'.join( [ '%02X' % x for x in input_src_mac ] )
+
+                input_dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+                input_dst_mac_str = ':'.join( [ '%02X' % x for x in input_dst_mac ] )
+
+                output_dst_mac = [ 0x00, 0x00, 0x00, 0x33, 0x33, 0x00 ]
+                output_dst_mac_str = ':'.join( [ '%02X' % x for x in output_dst_mac ] )
+
+                dip = sub_info[1]
+                ports = config[ "port_map" ].keys( )
+
+                inner_vlan = sub_info[2]
+                outer_vlan = sub_info[3]
+                internal_vlan = sub_info[5]
+
+                id = sub_info[0] + 10
+                ip_src = '192.168.5.5'
+                ip_dst = '192.168.0.{}'.format(sub_info[0])
+                parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=False,
+                        eth_dst=input_dst_mac_str, eth_src=input_src_mac_str, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+                pkt = str( parsed_pkt )
+
+                # print("Input Packet %s" % format_packet(pkt))
+
+                self.dataplane.send( port, pkt )
+
+                # build expect packet
+                exp_pkt = simple_tcp_packet( pktlen=108, dl_vlan_enable=True, vlan_vid=inner_vlan, outer_vlan=outer_vlan,
+                        eth_dst=output_dst_mac_str, eth_src=input_dst_mac_str, ip_ttl=63, ip_src=ip_src, ip_dst=ip_dst )
+                pkt = str( exp_pkt )
+
+                # print("Expected Packet %s" % format_packet(pkt))
+
+                verify_packet( self, pkt, out_port )
+                verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class UntaggedToDoubleChangeEthertype ( base_tests.SimpleDataPlane ):
+
+    def runTest( self ):
+        Groups = Queue.LifoQueue()
+
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "port count less than 2, can't run this case" )
+                return
+
+            input_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            input_src_mac_str = ':'.join( [ '%02X' % x for x in input_src_mac ] )
+
+            input_dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            input_dst_mac_str = ':'.join( [ '%02X' % x for x in input_dst_mac ] )
+
+            output_dst_mac = [ 0x00, 0x00, 0x00, 0x33, 0x33, 0x00 ]
+            output_dst_mac_str = ':'.join( [ '%02X' % x for x in output_dst_mac ] )
+
+            dip = 0xc0a80001
+            ports = config[ "port_map" ].keys( )
+
+            inner_vlan = 66
+            outer_vlan = 77
+            id = 10
+
+            port = ports[0]
+            out_port = ports[1]
+
+            # add l2 unfiltered interface group
+            l2_gid, l2_msg = add_one_l2_unfiltered_group( self.controller, out_port, True)
+
+            l3_msg = add_l3_unicast_group( self.controller, out_port, vlanid=4094, id=id,
+                        src_mac=input_dst_mac, dst_mac=output_dst_mac, gid=l2_gid)
+
+            do_barrier( self.controller )
+
+            # add vlan flow table
+            add_one_vlan_table_flow( self.controller, port, 1, 4094,
+                    flag=VLAN_TABLE_FLAG_ONLY_BOTH )
+
+            # add termination flow
+            if config["switch_type"] == "qmx":
+                add_termination_flow( self.controller, 0, 0x0800, input_dst_mac, 4094 )
+            else:
+                add_termination_flow( self.controller, port, 0x0800, input_dst_mac, 4094 )
+
+            add_unicast_routing_flow( self.controller, 0x0800, dip, 0xffffffff, l3_msg.group_id,
+                    vrf=0 )
+
+            add_one_egress_vlan_table_flow( self.controller, out_port, 4094 , inner_vlan, outer_vlan)
+
+            Groups._put( l2_gid )
+            Groups._put( l3_msg.group_id )
+
+            # add vlan flow table
+            add_one_egress_vlan_tpid_table_flow( self.controller, out_port, outer_vlan+0x1000 )
+            do_barrier( self.controller )
+
+            ip_src = '192.168.5.5'
+            ip_dst = '192.168.0.1'
+            parsed_pkt = simple_tcp_packet( pktlen=100,
+                                            dl_vlan_enable=False,
+                                            eth_dst=input_dst_mac_str,
+                                            eth_src=input_src_mac_str,
+                                            ip_ttl=64,
+                                            ip_src=ip_src,
+                                            ip_dst=ip_dst )
+            pkt = str( parsed_pkt )
+
+            print("Input Packet %s" % format_packet(pkt))
+
+            self.dataplane.send( port, pkt )
+
+            # build expect packet
+            exp_pkt = simple_tcp_packet_two_vlan( pktlen=108,
+                                                  out_dl_vlan_enable=True,
+                                                  out_vlan_vid=outer_vlan,
+                                                  out_vlan_tpid=0x88a8,
+                                                  in_dl_vlan_enable=True,
+                                                  in_vlan_vid=inner_vlan,
+                                                  eth_dst=output_dst_mac_str,
+                                                  eth_src=input_dst_mac_str,
+                                                  ip_ttl=63,
+                                                  ip_src=ip_src,
+                                                  ip_dst=ip_dst )
+            pkt = str( exp_pkt )
+
+            print("Expected Packet %s" % format_packet(pkt))
+
+            verify_packet( self, pkt, out_port )
+            verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class _MplsFwdInterfaceProblem_PW( base_tests.SimpleDataPlane ):
+    """
+    Reproduces the pseudowire bug with the wrongly set destination mac address.
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 1:
+                logging.info( "Port count less than 1, can't run this case" )
+                assert (False)
+                return
+
+            macs_to_test = [( [ 0x00, 0x00, 0x00, 0x11, 0x11, 0x00 ], [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ],  '00:00:00:11:11:00',  '00:00:00:22:22:00'),
+                            ( [ 0x00, 0x00, 0x00, 0x11, 0x22, 0x00 ], [ 0x00, 0x00, 0x00, 0x33, 0x33, 0x00 ],  '00:00:00:11:22:00',  '00:00:00:33:33:00'),
+                            ( [ 0x00, 0x00, 0x00, 0x11, 0x33, 0x00 ], [ 0x00, 0x00, 0x00, 0x44, 0x44, 0x00 ],  '00:00:00:11:33:00',  '00:00:00:44:44:00'),
+                            ( [ 0x00, 0x00, 0x00, 0x11, 0x44, 0x00 ], [ 0x00, 0x00, 0x00, 0x55, 0x55, 0x00 ],  '00:00:00:11:44:00',  '00:00:00:55:55:00'),
+                            ( [ 0x00, 0x00, 0x00, 0x11, 0x55, 0x00 ], [ 0x00, 0x00, 0x00, 0x66, 0x66, 0x00 ],  '00:00:00:11:55:00',  '00:00:00:66:66:00')]
+
+            for dummy_dst_mac, dst_mac, mac_dst_dummy, mac_dst in macs_to_test:
+
+                dip = 0xc0a80001
+                intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+
+                out_port = 12
+                port = 24
+                # Shift MPLS label and VLAN ID by 16 to avoid reserved values
+                vlan_id = port + 16
+                mpls_label = port + 16
+
+                in_port = 24
+                ip_src = '192.168.%02d.1' % (in_port)
+
+                # create dummy groups
+                id = port
+                l2_gid, l2_msg = add_one_l2_interface_group( self.controller, out_port, vlan_id, False, False)
+                mpls_gid, mpls_msg = add_mpls_intf_group( self.controller, l2_gid, dummy_dst_mac, intf_src_mac,
+                       vlan_id, id, send_barrier=True)
+                do_barrier( self.controller )
+
+                # PW Case.
+                raw_input("Press anything to move on with pseudowire rules, after that you should see the updated groups in the switch.")
+                logging.info("Installing entries for pseudowire!")
+                switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+                mpls_label      = 100
+                mpls_label_SR2 = 100 + 10
+                mpls_label_PW = 100 + 15
+
+                print("Install MPLS intf group for dst mac {0}", dst_mac)
+                # add MPLS interface group
+                mpls_intf_gid, mpls_intf_msg = add_mpls_intf_group(
+                    ctrl=self.controller,
+                    ref_gid=l2_gid,
+                    dst_mac=dst_mac,
+                    src_mac=intf_src_mac,
+                    vid=vlan_id,
+                    index=id,
+                    add=False,
+                    send_barrier=True
+                    )
+
+                # add MPLS flow with BoS=0
+                add_mpls_flow_pw(
+                    ctrl=self.controller,
+                    action_group_id=mpls_intf_gid,
+                    label=mpls_label_SR2,
+                    ethertype=0x8847,
+                    tunnel_index=1,
+                    bos=0
+                    )
+
+                # add Termination flow
+                add_termination_flow(
+                    ctrl=self.controller,
+                    in_port=in_port,
+                    eth_type=0x8847,
+                    dst_mac=intf_src_mac,
+                    vlanid=vlan_id,
+                    goto_table=23
+                    )
+
+                # add VLAN flows
+                add_one_vlan_table_flow(
+                    ctrl=self.controller,
+                    of_port=in_port,
+                    vlan_id=vlan_id,
+                    flag=VLAN_TABLE_FLAG_ONLY_TAG,
+                    )
+                add_one_vlan_table_flow(
+                    ctrl=self.controller,
+                    of_port=in_port,
+                    vlan_id=vlan_id,
+                    flag=VLAN_TABLE_FLAG_ONLY_UNTAG
+                    )
+                # Packet generation with sleep
+                time.sleep(2)
+                label_SR2 = (mpls_label_SR2, 0, 0, 32)
+                label_2 = (mpls_label_PW, 0, 1, 32)
+
+                # set to false to test if routing traffic
+                # comes through
+                raw_input("Press enter to send the packet, inspect the groups in the switch!")
+                print("Sending packet with dst mac {0} and labels {1}".format(switch_mac, [label_SR2, label_2]))
+                parsed_pkt = mpls_packet(
+                    pktlen=104,
+                    ip_ttl=63,
+                    label=[label_SR2, label_2],
+                    encapsulated_ethernet = True,
+                    eth_dst=switch_mac
+                )
+
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                expected_label = (mpls_label_PW, 0, 1, 31)
+                print("Expecting packet with dst mac {0} and labels {1}".format(mac_dst, [label_2]))
+                parsed_pkt =  mpls_packet(
+                    pktlen=100,
+                    ip_ttl=63,
+                    eth_dst=mac_dst,
+                    eth_src=switch_mac,
+                    label=[ expected_label ],
+                    encapsulated_ethernet = True
+                )
+
+                pkt = str( parsed_pkt )
+                verify_packet( self, pkt, out_port )
+                verify_no_packet( self, pkt, in_port )
+
+                delete_all_flows( self.controller )
+                delete_groups( self.controller, Groups )
+                delete_all_groups( self.controller )
+
+        finally:
+                delete_all_flows( self.controller )
+                delete_groups( self.controller, Groups )
+                delete_all_groups( self.controller )
+
+
+class VlanCrossConnect ( base_tests.SimpleDataPlane ):
+    """
+    Tries the cross connect functionality of the ofdpa switches.
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            # each entry represents a subscriber [id, ip in hex, inner_vlan, outer_vlan, ip in dot form]
+            subscriber_info = [ [10, 0xc0a80001, 12, 11, "192.168.0.1"] ]
+
+            index = 5
+            for sub_info in subscriber_info:
+
+                #print("Initializing rules for subscriber with id {0}".format(sub_info[0]))
+
+                input_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, sub_info[0] ]
+                input_src_mac_str = ':'.join( [ '%02X' % x for x in input_src_mac ] )
+
+                input_dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+                input_dst_mac_str = ':'.join( [ '%02X' % x for x in input_dst_mac ] )
+
+                output_dst_mac = [ 0x00, 0x00, 0x00, 0x33, 0x33, 0x00 ]
+                output_dst_mac_str = ':'.join( [ '%02X' % x for x in output_dst_mac ] )
+
+                dip = sub_info[1]
+                ports = config[ "port_map" ].keys( )
+
+                inner_vlan = sub_info[2]
+                outer_vlan = sub_info[3]
+
+                index = inner_vlan
+
+                port = ports[0]
+                out_port = ports[1]
+
+                # add l2 interface group, uncomment for unfiltered
+                l2_gid, l2_msg = add_one_l2_interface_group( self.controller, out_port, outer_vlan, True, True)
+                #i l2_gid, l2_msg = add_one_l2_unfiltered_group( self.controller, out_port, 1, True)
+
+                # add vlan flow table
+                add_one_vlan_table_flow( self.controller, port, inner_vlan, outer_vlan, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_STACKED )
+                add_one_vlan_1_table_flow_pw( self.controller, port, index, new_outer_vlan_id=outer_vlan ,outer_vlan_id=outer_vlan, inner_vlan_id=inner_vlan, cross_connect=True, send_barrier=True)
+                add_mpls_l2_port_flow(ctrl=self.controller, of_port=port, mpls_l2_port=port, tunnel_index=index, ref_gid=l2_gid, qos_index=0, goto=ACL_FLOW_TABLE)
+                index += 1
+
+                Groups._put( l2_gid )
+                do_barrier( self.controller )
+
+            for sub_info in subscriber_info:
+                #print("Sending packet for subscriber with id {0}".format(sub_info[0]))
+                input_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, sub_info[0] ]
+                input_src_mac_str = ':'.join( [ '%02X' % x for x in input_src_mac ] )
+
+                input_dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+                input_dst_mac_str = ':'.join( [ '%02X' % x for x in input_dst_mac ] )
+
+                dip = sub_info[1]
+                ports = config[ "port_map" ].keys( )
+
+                inner_vlan = sub_info[2]
+                outer_vlan = sub_info[3]
+
+                port = ports[0]
+                out_port = ports[1]
+
+                ip_src = sub_info[4]
+                ip_dst = '192.168.0.{}'.format(sub_info[0])
+                parsed_pkt = qinq_tcp_packet( pktlen=120, vlan_vid=inner_vlan, dl_vlan_outer=outer_vlan,
+                        eth_dst=input_dst_mac_str, eth_src=input_src_mac_str, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+                parsed_pkt = simple_tcp_packet_two_vlan( pktlen=120, out_dl_vlan_enable=True, in_dl_vlan_enable=True, in_vlan_vid=inner_vlan, out_vlan_vid=outer_vlan,
+                        eth_dst=input_dst_mac_str, eth_src=input_src_mac_str, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+
+                pkt = str( parsed_pkt )
+
+                self.dataplane.send( port, pkt )
+                verify_packet( self, pkt, out_port )
+                verify_no_other_packets( self )
+
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+@disabled
+class Lag( base_tests.SimpleDataPlane ):
+    """
+    Checks the L2 load balancing (LAG) functionality of the ofdpa switches.
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            ports = sorted(config[ "port_map" ].keys( ))
+            in_port = ports[0]
+            out_port = ports[1]
+
+            # add l2 interface unfiltered group
+            l2_o_gid, l2_o_msg = add_one_l2_unfiltered_group( self.controller, out_port, True)
+
+            # create l2 load-balance group
+            lag_gid, lag_msg = add_l2_loadbal_group(self.controller, 1, [l2_o_gid], True)
+            Groups.put(l2_o_gid, lag_gid)
+
+            # --- TEST 1: bridging with load-bal----
+            vlan_in_port_untagged = 31
+            # table 10 flows and bridging flows for dstMac+vlan -> l2-load-bal group
+            add_one_vlan_table_flow( self.controller, in_port, vlan_id=vlan_in_port_untagged, flag=VLAN_TABLE_FLAG_ONLY_BOTH,
+                                     send_barrier=True)
+            mac_dst = [ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 ]
+            mac_dst_str = '00:11:22:33:44:55'
+            add_bridge_flow( self.controller, mac_dst, vlan_in_port_untagged, lag_gid, True )
+            # untagged packet input becomes tagged packet at output
+            time.sleep(0.1)
+            pkt = str( simple_tcp_packet( pktlen=80, eth_dst=mac_dst_str ) )
+            exp_pkt = str( simple_tcp_packet( pktlen=84, dl_vlan_enable=True, vlan_vid=vlan_in_port_untagged, eth_dst=mac_dst_str ) )
+            self.dataplane.send( in_port, pkt )
+            verify_packet( self, exp_pkt, out_port )
+            verify_no_other_packets( self )
+
+            # --- TEST 2: flooding with load-bal ----
+            # flooding group --> load-bal group --> l2 unfiltered interface
+            floodmsg = add_l2_flood_group_with_gids( self.controller, [lag_gid] , vlan_in_port_untagged, id=0 )
+            Groups.put( floodmsg.group_id )
+            # add bridging flows for flooding groups
+            add_bridge_flow( self.controller, dst_mac=None, vlanid=vlan_in_port_untagged, group_id=floodmsg.group_id )
+            # unknown dstmac  packet input to hit flood group
+            un_mac_dst_str = '00:11:22:ff:ff:ff'
+            pkt = str( simple_tcp_packet( pktlen=80, eth_dst=un_mac_dst_str ) )
+            exp_pkt = str( simple_tcp_packet( pktlen=84, dl_vlan_enable=True, vlan_vid=vlan_in_port_untagged, eth_dst=un_mac_dst_str ) )
+            time.sleep(0.1)
+            self.dataplane.send( in_port, pkt )
+            verify_packet( self, exp_pkt, out_port )
+            verify_no_other_packets( self )
+
+            # --- TEST 3: editing load-bal ----
+            # create and add another l2 unfiltered interface group to the load-balancing group
+            l2_i_gid, l2_i_msg = add_one_l2_unfiltered_group( self.controller, in_port, True)
+            msg = mod_l2_loadbal_group(self.controller, 1, [l2_o_gid, l2_i_gid], True)
+            self.dataplane.send( in_port, pkt )
+            verify_packet( self, exp_pkt, out_port )
+
+            # delete all buckets in loadbal group
+            msg = mod_l2_loadbal_group(self.controller, 1, [], True)
+            time.sleep(0.1)
+            self.dataplane.send( in_port, pkt )
+            verify_no_other_packets( self ) # no buckets
+
+            # only input port in load balancing group
+            msg = mod_l2_loadbal_group(self.controller, 1, [l2_i_gid], True)
+            self.dataplane.send( in_port, pkt )
+            verify_no_other_packets( self ) # packet should not be sent out of in port
+
+            # remove input port and add output port in lag group
+            msg = mod_l2_loadbal_group(self.controller, 1, [l2_o_gid], True)
+            time.sleep(0.1)
+            self.dataplane.send( in_port, pkt )
+            verify_packet( self, exp_pkt, out_port )
+            verify_no_other_packets( self )
+
+        finally:
+            #print("done")
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class FloodLb( base_tests.SimpleDataPlane ):
+    """
+    Checks L2 flood group pointing to L2 load balance group with 2 buckets (unfiltered).
+    The packet from in_port should not be seen on the out_port
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            ports = sorted(config[ "port_map" ].keys( ))
+            in_port = ports[0]
+            out_port = ports[1]
+            vlan_in_port_untagged = 31
+
+            # add l2 unfiltered interface group for outport
+            l2_i_gid, l2_i_msg = add_one_l2_unfiltered_group( self.controller, in_port, True)
+            l2_o_gid, l2_o_msg = add_one_l2_unfiltered_group( self.controller, out_port, True)
+
+            # create l2 load-balance group
+            lag_gid, lag_msg = add_l2_loadbal_group(self.controller, 1, [l2_i_gid, l2_o_gid], True)
+
+            # create l2 flood group with mix of l2i and l2-loadbal
+            floodmsg = add_l2_flood_group_with_gids( self.controller, [lag_gid] , vlan_in_port_untagged, id=0, send_barrier=True )
+            Groups.put( l2_i_gid )
+            Groups.put( l2_o_gid )
+            Groups.put( lag_gid )
+            Groups.put( floodmsg.group_id )
+
+            # table 10 flows for untagged input
+            add_one_vlan_table_flow( self.controller, in_port, vlan_id=vlan_in_port_untagged, flag=VLAN_TABLE_FLAG_ONLY_BOTH,
+                                     send_barrier=True)
+            add_one_vlan_table_flow( self.controller, out_port, vlan_id=vlan_in_port_untagged, flag=VLAN_TABLE_FLAG_ONLY_BOTH,
+                                     send_barrier=True)
+
+            # add bridging flows for flooding groups
+            add_bridge_flow( self.controller, dst_mac=None, vlanid=vlan_in_port_untagged, group_id=floodmsg.group_id )
+            # unknown dstmac packet will hit flood group
+            un_mac_dst_str = '00:11:22:ff:ff:ff'
+
+            # check one direction -> packet enters through inport should not be seen on the outport
+            pkt = str( simple_tcp_packet( pktlen=80, eth_dst=un_mac_dst_str ) )
+            self.dataplane.send( in_port, pkt )
+            verify_no_other_packets( self )
+
+            # check other direction -> packet enters through outport should not be seen on the inport
+            pkt = str( simple_tcp_packet( pktlen=80, eth_dst=un_mac_dst_str ) )
+            self.dataplane.send( out_port, pkt )
+            verify_no_other_packets( self )
+
+        finally:
+            #print("done")
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class FloodMixUntagged( base_tests.SimpleDataPlane ):
+    """
+    Checks the combination of L2 filtered and L2 load balancing (LAG) groups
+    in a flooding group
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            ports = sorted(config[ "port_map" ].keys( ))
+            in_port = ports[0]
+            out_port = ports[1]
+            vlan_in_port_untagged = 31
+
+            # add l2 unfiltered interface group for outport
+            l2_o_gid, l2_o_msg = add_one_l2_unfiltered_group( self.controller, out_port, True)
+
+            # create l2 load-balance group
+            lag_gid, lag_msg = add_l2_loadbal_group(self.controller, 1, [l2_o_gid], True)
+
+            # create l2 interface (filtered) group for inport
+            l2_i_gid, l2_i_msg = add_one_l2_interface_group( self.controller, in_port, vlan_in_port_untagged,
+                                                             is_tagged=False, send_barrier=True)
+
+            # create l2 flood group with mix of l2i and l2-loadbal
+            floodmsg = add_l2_flood_group_with_gids( self.controller, [lag_gid, l2_i_gid] , vlan_in_port_untagged, id=0 )
+            Groups.put( l2_o_gid )
+            Groups.put( lag_gid )
+            Groups.put( l2_i_gid )
+            Groups.put( floodmsg.group_id )
+
+            # table 10 flows for untagged input
+            add_one_vlan_table_flow( self.controller, in_port, vlan_id=vlan_in_port_untagged, flag=VLAN_TABLE_FLAG_ONLY_BOTH,
+                                     send_barrier=True)
+
+            # add bridging flows for flooding groups
+            add_bridge_flow( self.controller, dst_mac=None, vlanid=vlan_in_port_untagged, group_id=floodmsg.group_id )
+            # unknown dstmac packet will hit flood group
+            un_mac_dst_str = '00:11:22:ff:ff:ff'
+
+            # check one direction -> packet enters through filtered port (inport) and exits through
+            # unfiltered port (outport) via the flood and lag groups
+            pkt = str( simple_tcp_packet( pktlen=80, eth_dst=un_mac_dst_str ) )
+            exp_pkt = str( simple_tcp_packet( pktlen=84, dl_vlan_enable=True, vlan_vid=vlan_in_port_untagged, eth_dst=un_mac_dst_str ) )
+            self.dataplane.send( in_port, pkt )
+            verify_packet( self, exp_pkt, out_port )
+            verify_no_other_packets( self )
+
+            # check other direction -> packet enters through unfiltered port (outport) and exits through
+            # filtered port (inport) via the flood group
+            add_one_vlan_table_flow( self.controller, out_port, vlan_id=vlan_in_port_untagged, flag=VLAN_TABLE_FLAG_ONLY_BOTH,
+                                     send_barrier=True)
+            pkt = str( simple_tcp_packet( pktlen=80, eth_dst=un_mac_dst_str ) )
+            exp_pkt = pkt # ingress packet gets internal vlan 31 which gets popped at l2 interface group before egress
+            self.dataplane.send( out_port, pkt )
+            verify_packet( self, exp_pkt, in_port )
+            verify_no_other_packets( self )
+
+        finally:
+            print("done")
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class FloodMixTagged( base_tests.SimpleDataPlane ):
+    """
+    Checks the combination of L2 filtered and L2 load balancing (LAG) groups
+    in a flooding group
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            ports = sorted(config[ "port_map" ].keys( ))
+            in_port = ports[0]
+            out_port = ports[1]
+            vlan_in_port_untagged = 31
+
+            # add l2 unfiltered interface group for outport
+            l2_o_gid, l2_o_msg = add_one_l2_unfiltered_group( self.controller, out_port, True)
+
+            # create l2 load-balance group
+            lag_gid, lag_msg = add_l2_loadbal_group(self.controller, 1, [l2_o_gid], True)
+
+            # create l2 interface (filtered) group for inport
+            l2_i_gid, l2_i_msg = add_one_l2_interface_group( self.controller, in_port, vlan_in_port_untagged,
+                                                             is_tagged=True, send_barrier=True)
+
+            # create l2 flood group with mix of l2i and l2-loadbal
+            floodmsg = add_l2_flood_group_with_gids( self.controller, [lag_gid, l2_i_gid] , vlan_in_port_untagged, id=0 )
+            Groups.put( l2_o_gid )
+            Groups.put( lag_gid )
+            Groups.put( l2_i_gid )
+            Groups.put( floodmsg.group_id )
+
+            # table 10 flows for tagged in_port. Note: VLAN in table 10 must be wildcarded for an unfiltered port
+            add_vlan_table_flow_allow_all_vlan(self.controller, in_port, send_barrier=True)
+
+            # add bridging flows for flooding groups
+            add_bridge_flow( self.controller, dst_mac=None, vlanid=vlan_in_port_untagged, group_id=floodmsg.group_id )
+            # unknown dstmac packet will hit flood group
+            un_mac_dst_str = '00:11:22:ff:ff:ff'
+
+            # check one direction -> packet enters through unfiltered port (inport) and exits through
+            # unfiltered port (outport) via the flood and lag groups
+            pkt = str( simple_tcp_packet( pktlen=80, dl_vlan_enable=True, vlan_vid=vlan_in_port_untagged, eth_dst=un_mac_dst_str ) )
+            exp_pkt = pkt
+            self.dataplane.send( in_port, pkt )
+            verify_packet( self, exp_pkt, out_port )
+            verify_no_other_packets( self )
+
+            # check other direction -> packet enters through unfiltered port (outport) and exits through
+            # unfiltered port (inport) via the flood group
+
+            # table 10 flows for tagged out_port. Note: VLAN must be wildcarded for an unfiltered port
+            add_vlan_table_flow_allow_all_vlan(self.controller, out_port, send_barrier=True)
+            pkt = str( simple_tcp_packet( pktlen=80, dl_vlan_enable=True, vlan_vid=vlan_in_port_untagged, eth_dst=un_mac_dst_str ) )
+            exp_pkt = pkt
+            self.dataplane.send( out_port, pkt )
+            verify_packet( self, exp_pkt, in_port )
+            verify_no_other_packets( self )
+
+        finally:
+            print("done")
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class LagMix( base_tests.SimpleDataPlane ):
+    """
+    Checks the combination of L2 filtered and unfiltered interface groups
+    in a L2 load balancing (LAG) group - this should not work according to spec
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            ports = sorted(config[ "port_map" ].keys( ))
+            in_port = ports[0]
+            out_port = ports[1]
+            vlan_in_port_untagged = 31
+
+            # add l2 unfiltered interface group
+            l2_o_gid, l2_o_msg = add_one_l2_unfiltered_group( self.controller, out_port, True)
+
+            # create  l2 interface (filtered) group
+            l2_i_gid, l2_i_msg = add_one_l2_interface_group( self.controller, in_port, vlan_in_port_untagged,
+                                                             is_tagged=False, send_barrier=True)
+
+            # create l2 load-balance group with a mix of filtered and unfiltered groups
+            """
+            XXX the following does not work - the group does not get created but curiously we don't get an openflow
+            error message. The ofdpa logs show
+            ofdbGroupBucketValidate: Referenced Group Id 0x1f000c not of type L2 Unfiltered Interface.
+            We do get an openflow error message for the flood group that follows because it cannot
+            find the lag group it points to (because it did not get created).
+            """
+            lag_gid, lag_msg = add_l2_loadbal_group(self.controller, 1, [l2_o_gid, l2_i_gid], True)
+
+            # create l2 flood group to point to lag group
+            floodmsg = add_l2_flood_group_with_gids( self.controller, [lag_gid] , vlan_in_port_untagged, id=0 )
+            Groups.put( floodmsg.group_id, l2_i_gid, lag_gid )
+            Groups.put( l2_o_gid )
+
+        finally:
+            #print("done")
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+@disabled
+class LagXconn( base_tests.SimpleDataPlane ):
+    """
+    Checks the L2 load balancing (LAG) with vlan crossconnects.
+    Note that for this to work, basic VlanCrossConnect test above (without LAG) should work first
+    Note: this doesn't work on XGS or QMX yet with premium 1.1.7
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            ports = sorted(config[ "port_map" ].keys( ))
+            in_port = ports[0]
+            out_port = ports[1]
+
+            # add l2 interface unfiltered group
+            l2_o_gid, l2_o_msg = add_one_l2_unfiltered_group( self.controller, out_port, True)
+
+            # create l2 load-balance group
+            lag_gid, lag_msg = add_l2_loadbal_group(self.controller, 1, [l2_o_gid], True)
+            Groups.put(l2_o_gid, lag_gid)
+
+            # a subscriber [id, ip in hex, inner_vlan, outer_vlan, ip in dot form]
+            sub_info = [10, 0xc0a80001, 12, 11, "192.168.0.1"]
+
+            input_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, sub_info[0] ]
+            input_src_mac_str = ':'.join( [ '%02X' % x for x in input_src_mac ] )
+            input_dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            input_dst_mac_str = ':'.join( [ '%02X' % x for x in input_dst_mac ] )
+            output_dst_mac = [ 0x00, 0x00, 0x00, 0x33, 0x33, 0x00 ]
+            output_dst_mac_str = ':'.join( [ '%02X' % x for x in output_dst_mac ] )
+
+            dip = sub_info[1]
+            ports = config[ "port_map" ].keys( )
+            inner_vlan = sub_info[2]
+            outer_vlan = sub_info[3]
+            index = inner_vlan
+            port = ports[0]
+            out_port = ports[1]
+
+            # add vlan flow table
+            add_one_vlan_table_flow( self.controller, port, inner_vlan, outer_vlan, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_STACKED )
+            add_one_vlan_1_table_flow_pw( self.controller, port, index, new_outer_vlan_id=outer_vlan, outer_vlan_id=outer_vlan,
+                                          inner_vlan_id=inner_vlan, cross_connect=True, send_barrier=True)
+            """
+            XXX The following flow in table 13 is rejected by the switch (qmx) probably due to the reference to lag group
+            ofdpa logs say: 08-22 00:43:10.344338 [ofstatemanager] Error from Forwarding while inserting flow: Unknown error
+            """
+            add_mpls_l2_port_flow(ctrl=self.controller, of_port=port, mpls_l2_port=port, tunnel_index=index, ref_gid=lag_gid,
+                                  qos_index=0, goto=ACL_FLOW_TABLE)
+            do_barrier( self.controller )
+
+            ip_src = sub_info[4]
+            ip_dst = '192.168.0.{}'.format(sub_info[0])
+            parsed_pkt = qinq_tcp_packet( pktlen=120, vlan_vid=inner_vlan, dl_vlan_outer=outer_vlan,
+                                          eth_dst=input_dst_mac_str, eth_src=input_src_mac_str, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+            parsed_pkt = simple_tcp_packet_two_vlan( pktlen=120, out_dl_vlan_enable=True, in_dl_vlan_enable=True,
+                                                     in_vlan_vid=inner_vlan, out_vlan_vid=outer_vlan,
+                                                     eth_dst=input_dst_mac_str, eth_src=input_src_mac_str,
+                                                     ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
+
+            pkt = str( parsed_pkt )
+            self.dataplane.send( port, pkt )
+            verify_packet( self, pkt, out_port )
+            verify_no_other_packets( self )
+
+        finally:
+            #print("done")
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+@disabled
+class LagRouting( base_tests.SimpleDataPlane ):
+    """
+    Checks the L2 load balancing (LAG) with routing flows.
+    Specifically route -> L3Unicast -> Lag -> L2 Unfiltered interface
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                return
+
+            ports = sorted(config[ "port_map" ].keys( ))
+            in_port = ports[0]
+            out_port = ports[1]
+
+            # add l2 interface unfiltered group
+            l2_o_gid, l2_o_msg = add_one_l2_unfiltered_group( self.controller, out_port, True)
+
+            # create l2 load-balance group
+            lag_gid, lag_msg = add_l2_loadbal_group(self.controller, 1, [l2_o_gid], True)
+            Groups.put(l2_o_gid, lag_gid)
+
+            intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
+            dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
+            dip = 0xc0a80001
+            vlan_id = 31
+
+            # create L3 Unicast group to point to Lag group
+            l3_msg = add_l3_unicast_group( self.controller, out_port, vlanid=vlan_id, id=vlan_id,
+                                           src_mac=intf_src_mac, dst_mac=dst_mac, gid=lag_gid )
+            # add vlan flow table
+            add_one_vlan_table_flow( self.controller, in_port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
+            # add termination flow
+            if config["switch_type"] == "qmx":
+                add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+            else:
+                add_termination_flow( self.controller, in_port, 0x0800, intf_src_mac, vlan_id )
+            # add unicast routing flow
+            add_unicast_routing_flow( self.controller, 0x0800, dip, 0xffffffff, l3_msg.group_id )
+
+            Groups.put( l3_msg.group_id )
+            do_barrier( self.controller )
+
+            switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+            mac_src = '00:00:00:22:22:%02X' % (in_port)
+            ip_src = '192.168.0.2'
+            ip_dst = '192.168.0.1'
+            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True,
+                                            vlan_vid=vlan_id, eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64,
+                                            ip_src=ip_src, ip_dst=ip_dst )
+            pkt = str( parsed_pkt )
+            self.dataplane.send( in_port, pkt )
+            # build expected packet
+            mac_dst = '00:00:00:22:22:00'
+            exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True,
+                                         vlan_vid=vlan_id, eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=63,
+                                         ip_src=ip_src, ip_dst=ip_dst )
+            pkt = str( exp_pkt )
+            verify_packet( self, pkt, out_port )
+            verify_no_other_packets( self )
+
+        finally:
+            #print("done")
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+class FabricSW_OF_EAPOL_TC_0060(base_tests.SimpleDataPlane):
+    """
+    To verify double VLAN tagged EAPOL packets can be matched and sent to controller.
+    """
+
+    def runTest(self):
+        try:
+            eth_type_eapol = 0x888e
+            eth_type_non_eapol = 0x88ee
+            eth_type = 0x8100
+            vlan_id100 = 100
+            vlanid200 = 200
+
+            logging.info("Step 1")
+            logging.info("Add a flow to TABLE-10 to match VLAN ID '100' for packets received at Data Port 1 and action transition to TABLE-20.")
+
+            ports = sorted(config["port_map"].keys())
+            for port in ports:
+                add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id100, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+
+            add_acl_rule(self.controller, eth_type=eth_type_eapol)
+
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.eth_type(eth_type_eapol))
+
+            logging.info("Step 2")
+            logging.info("Creating a double tagged vlan packet with ethernet type {}".format(hex(eth_type_eapol)))
+            parsed_pkt = simple_ether_packet_two_vlan(out_dl_vlan_enable=True,
+                                                      in_dl_vlan_enable=True,
+                                                      out_vlan_tpid=eth_type,
+                                                      in_vlan_tpid=eth_type_eapol,
+                                                      out_vlan_vid=vlan_id100,
+                                                      in_vlan_vid=vlanid200)
+            vlan_pkt = str(parsed_pkt)
+
+            logging.info("Step 3")
+            logging.info("Creating a double tagged vlan packet with ethernet type {}".format(hex(eth_type_non_eapol)))
+            parsed_pkt_non_eapol = simple_ether_packet_two_vlan(out_dl_vlan_enable=True,
+                                                      in_dl_vlan_enable=True,
+                                                      out_vlan_tpid=eth_type,
+                                                      in_vlan_tpid=eth_type_non_eapol,
+                                                      out_vlan_vid=vlan_id100,
+                                                      in_vlan_vid=vlanid200)
+            vlan_pkt_non_eapol = str(parsed_pkt_non_eapol)
+
+            logging.info("Step 4")
+            logging.info(
+                "Send double tagged vlan packet with ethernet type {} to port {}".format(hex(eth_type_eapol), ports[0]))
+            self.dataplane.send(ports[0], vlan_pkt)
+            verify_packet_in(self, vlan_pkt, ports[0], ofp.OFPR_ACTION)
+
+            logging.info("Step 5")
+            logging.info(
+                "Send double tagged vlan packet with ethernet type {} to port {}".format(hex(eth_type_non_eapol), ports[0]))
+            self.dataplane.send(ports[0], vlan_pkt_non_eapol)
+            verify_no_packet_in(self, vlan_pkt_non_eapol, ports[0])
+
+            logging.info("Step 6 Cleanup flows")
+            delete_all_flows(self.controller)
+            time.sleep(1)
+
+            logging.info("Step 7")
+            logging.info("Add flows again ID=10 and ID=60")
+            for port in ports:
+                add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id100, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+
+            add_acl_rule(self.controller, eth_type=eth_type_eapol)
+
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.eth_type(eth_type_eapol))
+            time.sleep(1)
+
+            logging.info("Step 8")
+            logging.info(
+                "Send double tagged vlan packet with ethernet type {} to port {}".format(hex(eth_type_eapol), ports[0]))
+            self.dataplane.send(ports[0], vlan_pkt)
+            verify_packet_in(self, vlan_pkt, ports[0], ofp.OFPR_ACTION)
+
+
+        finally:
+            delete_all_flows( self.controller )
+            delete_all_groups( self.controller )
+            logging.info("End of Test")
+
+
+
+class FabricSW_OF_ARP_TC_0065(base_tests.SimpleDataPlane):
+    """
+    To verify double VLAN tagged ARP packets can be matched and sent to controller.
+    """
+
+    def runTest(self):
+        try:
+            eth_type_arp = 0x806
+            eth_type_non_arp = 0x888e
+            eth_type = 0x8100
+            vlan_id100 = 100
+            vlanid200 = 200
+
+            logging.info("Step 1")
+            logging.info("Add a flow to TABLE-10 to match VLAN ID '100' for packets received at Data Port 1 and action transition to TABLE-20.")
+
+            ports = sorted(config["port_map"].keys())
+            for port in ports:
+                add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id100, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+
+            add_acl_rule(self.controller, eth_type=eth_type_arp)
+
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.eth_type(eth_type_arp))
+
+            logging.info("Step 2")
+            logging.info("Creating a double tagged vlan packet with ethernet type {}".format(hex(eth_type_arp)))
+            parsed_pkt = simple_ether_packet_two_vlan(out_dl_vlan_enable=True,
+                                                      in_dl_vlan_enable=True,
+                                                      out_vlan_tpid=eth_type,
+                                                      in_vlan_tpid=eth_type_arp,
+                                                      out_vlan_vid=vlan_id100,
+                                                      in_vlan_vid=vlanid200)
+            vlan_pkt = str(parsed_pkt)
+
+            logging.info("Step 3")
+            logging.info("Creating a double tagged vlan packet with ethernet type {}".format(hex(eth_type_non_arp)))
+            parsed_pkt_non_arp = simple_ether_packet_two_vlan(out_dl_vlan_enable=True,
+                                                      in_dl_vlan_enable=True,
+                                                      out_vlan_tpid=eth_type,
+                                                      in_vlan_tpid=eth_type_non_arp,
+                                                      out_vlan_vid=vlan_id100,
+                                                      in_vlan_vid=vlanid200)
+            vlan_pkt_non_arp = str(parsed_pkt_non_arp)
+
+            logging.info("Step 4")
+            logging.info(
+                "Send double tagged vlan packet with ethernet type {} to port {}".format(hex(eth_type_arp), ports[0]))
+            self.dataplane.send(ports[0], vlan_pkt)
+            verify_packet_in(self, vlan_pkt, ports[0], ofp.OFPR_ACTION)
+
+            logging.info("Step 5")
+            logging.info(
+                "Send double tagged vlan packet with ethernet type {} to port {}".format(hex(eth_type_non_arp), ports[0]))
+            self.dataplane.send(ports[0], vlan_pkt_non_arp)
+            verify_no_packet_in(self, vlan_pkt_non_arp, ports[0])
+
+            logging.info("Step 6 Cleanup flows")
+            delete_all_flows(self.controller)
+            time.sleep(1)
+
+            logging.info("Step 7")
+            logging.info("Add flows again ID=10 and ID=60")
+            for port in ports:
+                add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id100, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+
+            add_acl_rule(self.controller, eth_type=eth_type_arp)
+
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.eth_type(eth_type_arp))
+            time.sleep(1)
+
+            logging.info("Step 8")
+            logging.info(
+                "Send double tagged vlan packet with ethernet type {} to port {}".format(hex(eth_type_arp), ports[0]))
+            self.dataplane.send(ports[0], vlan_pkt)
+            verify_packet_in(self, vlan_pkt, ports[0], ofp.OFPR_ACTION)
+
+
+        finally:
+            delete_all_flows(self.controller)
+            delete_all_groups(self.controller)
+            logging.info("End of Test")
+
+@disabled
+class FabricSW_OF_ARP_LAG_TC(base_tests.SimpleDataPlane):
+    """
+    To verify double VLAN tagged ARP packets received over a LAG interface can be matched and sent to controller.
+
+    TODO: Need to add step: Create a logical port (LAG) and bind data ports 1 and 2 to the logical port.
+    """
+
+    def runTest(self):
+        try:
+            eth_type_arp = 0x806
+            eth_type_non_arp = 0x888e
+            eth_type = 0x8100
+            vlan_id100 = 100
+            vlanid200 = 200
+
+            logging.info("Step 1")
+            logging.info(
+                "Create a logical port (LAG) and bind data ports 1 and 2 to the logical port.")
+
+            # TODO: add LAG here:
+
+            logging.info("Step 2")
+            logging.info("Add a flow to TABLE-10 to match VLAN ID '100' for packets received at Data Port 1 and action transition to TABLE-20.")
+
+            ports = sorted(config["port_map"].keys())
+            for port in ports:
+                add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id100, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+
+            add_acl_rule(self.controller, eth_type=eth_type_arp)
+
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.eth_type(eth_type_arp))
+
+            logging.info("Step 3")
+            logging.info("Creating a double tagged vlan packet with ethernet type {}".format(hex(eth_type_arp)))
+            parsed_pkt = simple_ether_packet_two_vlan(out_dl_vlan_enable=True,
+                                                      in_dl_vlan_enable=True,
+                                                      out_vlan_tpid=eth_type,
+                                                      in_vlan_tpid=eth_type_arp,
+                                                      out_vlan_vid=vlan_id100,
+                                                      in_vlan_vid=vlanid200)
+            vlan_pkt = str(parsed_pkt)
+
+            logging.info("Step 4")
+            logging.info("Creating a double tagged vlan packet with ethernet type {}".format(hex(eth_type_non_arp)))
+            parsed_pkt_non_eapol = simple_ether_packet_two_vlan(out_dl_vlan_enable=True,
+                                                      in_dl_vlan_enable=True,
+                                                      out_vlan_tpid=eth_type,
+                                                      in_vlan_tpid=eth_type_non_arp,
+                                                      out_vlan_vid=vlan_id100,
+                                                      in_vlan_vid=vlanid200)
+            vlan_pkt_non_eapol = str(parsed_pkt_non_eapol)
+
+            logging.info("Step 5")
+            for port in ports:
+                logging.info(
+                    "Send double tagged vlan packet with ethernet type {} to port {}".format(hex(eth_type_arp), port))
+                self.dataplane.send(port, vlan_pkt)
+                verify_packet_in(self, vlan_pkt, port, ofp.OFPR_ACTION)
+
+            logging.info("Step 7")
+            logging.info(
+                "Send double tagged vlan packet with ethernet type {} to port {}".format(hex(eth_type_non_arp), ports[0]))
+            self.dataplane.send(ports[0], vlan_pkt_non_eapol)
+            verify_no_packet_in(self, vlan_pkt_non_eapol, ports[0])
+
+            logging.info("Step 8 Cleanup flows")
+            delete_all_flows(self.controller)
+
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.eth_type(eth_type_arp))
+
+            logging.info("Step 9")
+            logging.info(
+                "Send double tagged vlan packet with ethernet type {} to port {}".format(hex(eth_type_arp), ports[0]))
+            self.dataplane.send(ports[0], vlan_pkt)
+            verify_no_packet_in(self, vlan_pkt, ports[0])
+
+
+        finally:
+            delete_all_flows( self.controller )
+            delete_all_groups( self.controller )
+            logging.info("End of Test")
+
+
+class FabricSW_OF_VLANPUSH_TC_0070(base_tests.SimpleDataPlane):
+    """
+    To verify a VLAN tag can be pushed into an untagged packet received on a physical interface.
+    """
+
+    def runTest(self):
+        try:
+            vlan_id100 = 100
+            ports = sorted(config["port_map"].keys())
+
+            logging.info("Step 1")
+            logging.info("Add a flow to TABLE-10 to match untagged packets received in Data Port 1 and immediate "
+                         "action to insert VLAN tag {} and transition to TABLE-20.".format(vlan_id100))
+            add_one_vlan_table_flow(ctrl=self.controller, of_port=ports[0], vlan_id=vlan_id100, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+            add_one_vlan_table_flow(ctrl=self.controller, of_port=ports[0], vlan_id=vlan_id100, flag=VLAN_TABLE_FLAG_ONLY_UNTAG)
+
+            logging.info("Step 2")
+            logging.info("Add a flow to TABLE-60 to match VLAN tag {} and action Send to Controller".format(vlan_id100))
+            add_acl_rule(ctrl=self.controller, vlan_id=vlan_id100)
+
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.vlan_vid(vlan_id100))
+
+            logging.info("Step 3")
+            logging.info("Creating an untagged vlan packet")
+            parsed_pkt = simple_ether_packet_two_vlan(out_dl_vlan_enable=False,
+                                                      in_dl_vlan_enable=False)
+            vlan_pkt = str(parsed_pkt)
+
+            logging.info("Step 4")
+            logging.info("Send untagged packet to port {}".format(ports[0]))
+            self.dataplane.send(ports[0], vlan_pkt)
+            verify_packet_in(self, vlan_pkt, ports[0], ofp.OFPR_ACTION)
+
+            logging.info("Step 6 Cleanup flows")
+            delete_all_flows(self.controller)
+
+            logging.info("Step 5")
+            logging.info("Send untagged packet to port {}".format(ports[0]))
+            self.dataplane.send(ports[0], vlan_pkt)
+            verify_no_packet_in(self, vlan_pkt, ports[0])
+
+
+        finally:
+            delete_all_flows(self.controller)
+            delete_all_groups(self.controller)
+            logging.info("End of Test")
+
+
+class FabricSW_OF_LLDP_TC_0075(base_tests.SimpleDataPlane):
+    """
+    To verify LLDP packets received on a physical interface can be matched and sent to Controller.
+    """
+
+    def runTest(self):
+        try:
+            eth_type_lldp = 0x88cc
+            eth_type_non_lldp = 0x88ee
+
+            similar_steps(eth_type_lldp, eth_type_non_lldp, self)
+
+        finally:
+            delete_all_flows(self.controller)
+            delete_all_groups(self.controller)
+            logging.info("End of Test")
+
+
+class FabricSW_OF_BDDP_TC_0080(base_tests.SimpleDataPlane):
+    """
+    To verify BDDP packets received on a physical interface can be matched and sent to Controller.
+    """
+
+    def runTest(self):
+        try:
+            eth_type_bddp = 0x8942
+            eth_type_non_bddp = 0x888e
+
+            similar_steps(eth_type_bddp, eth_type_non_bddp, self)
+
+        finally:
+            delete_all_flows(self.controller)
+            delete_all_groups(self.controller)
+            logging.info("End of Test")
+
+
+class FabricSW_OF_VLANXConnect_Single_TC_0085(base_tests.SimpleDataPlane):
+    """
+    Verify QnQ traffic flooding between 2 cross (one-to-one) connected physical interfaces.
+    """
+
+    def runTest(self):
+        groups = Queue.LifoQueue()
+        try:
+            ports = sorted(config["port_map"].keys())
+            vlan_id = 100
+            vlan_id101 = 101
+
+            for port in ports:
+                L2gid, l2msg = add_one_l2_interface_group(self.controller, port, vlan_id, True, False)
+                add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+                groups.put(L2gid)
+
+            msg = add_l2_flood_group(self.controller, ports, vlan_id, vlan_id)
+            groups.put(msg.group_id)
+            add_bridge_flow(self.controller, None, vlan_id, msg.group_id, True)
+
+            #do_barrier(self.controller)
+
+            logging.info(
+                "Add a flow to TABLE-60 to match vlan {} and action Send to Controller".format(vlan_id))
+            add_acl_rule(self.controller, vlan_id=vlan_id)
+
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.vlan_vid(vlan_id))
+
+            # verify flood
+            logging.info("Creating a double tagged vlan packet with outer vlan id {}".format(vlan_id))
+            for ofport in ports:
+                # change dest based on port number
+                mac_src = '00:12:34:56:78:%02X' % ofport
+                parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
+                        out_vlan_vid=vlan_id, in_dl_vlan_enable=True, in_vlan_vid=10,
+                        eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+                pkt = str(parsed_pkt)
+                self.dataplane.send(ofport, pkt)
+                # self won't rx packet
+                verify_no_packet(self, pkt, ofport)
+                # others will rx packet
+                tmp_ports = list(ports)
+                tmp_ports.remove(ofport)
+                verify_packets(self, pkt, tmp_ports)
+
+            logging.info("Creating a double tagged vlan packet with outer vlan id {}".format(vlan_id101))
+            mac_src = '00:12:34:56:78:%02X' % ports[0]
+            parsed_pkt_101 = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
+                                                        out_vlan_vid=vlan_id101, in_dl_vlan_enable=True, in_vlan_vid=10,
+                                                        eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+            pkt_101 = str(parsed_pkt_101)
+            logging.info("Send double tugged packet to port {}".format(ports[0]))
+            self.dataplane.send(ports[0], pkt_101)
+
+            logging.info("Verify the packet is not flooded to data port2 with outer vlan id {}".format(vlan_id101))
+            verify_no_packet(self, pkt_101, ports[1])
+
+            logging.info("Cleanup flows")
+            delete_all_flows(self.controller)
+
+            logging.info("Send double tugged packet to port {}".format(ports[1]))
+            self.dataplane.send(ports[1], pkt)
+
+            logging.info("Verify the packet is not flooded to data port1 with outer vlan id {}".format(vlan_id))
+            verify_no_packet(self, pkt, ports[0])
+
+        finally:
+            delete_all_flows(self.controller)
+            delete_groups(self.controller, groups)
+            delete_all_groups(self.controller)
+            logging.info("End of Test")
+
+
+class FabricSW_OF_VLANXConnect_Multi_TC_0090(base_tests.SimpleDataPlane):
+    """
+    Verify QnQ traffic flooding between Many-to-One (multiple S tags to single BNG) and One-Many (Single BNG to
+    multiple S tags) cross connected physical interfaces.
+    """
+
+    def runTest(self):
+        groups = Queue.LifoQueue()
+        try:
+            ports = sorted(config["port_map"].keys())
+            vlan_id100 = 100
+            vlan_id101 = 101
+            vlan_id102 = 102
+
+            # Create VLAN100 flow and tables for port1 and port4
+            tmp_ports = list(ports)
+            tmp_ports.remove(ports[1])
+            tmp_ports.remove(ports[2])
+
+            for port in tmp_ports:
+                L2gid, l2msg = add_one_l2_interface_group(self.controller, port, vlan_id100, True, False)
+                add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id100, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+                groups.put(L2gid)
+
+            msg = add_l2_flood_group(self.controller, tmp_ports, vlan_id100, vlan_id100)
+            groups.put(msg.group_id)
+            add_bridge_flow(self.controller, None, vlan_id100, msg.group_id, True)
+
+            # do_barrier(self.controller)
+
+            logging.info(
+                "Add a flow to TABLE-60 to match vlan {} and action Send to Controller".format(vlan_id100))
+            add_acl_rule(self.controller, vlan_id=vlan_id100)
+
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.vlan_vid(vlan_id100))
+
+            # Create VLAN101 flow and tables for port2 and port4
+            tmp_ports1 = list(ports)
+            tmp_ports1.remove(ports[0])
+            tmp_ports1.remove(ports[2])
+
+            for port in tmp_ports1:
+                L2gid, l2msg = add_one_l2_interface_group(self.controller, port, vlan_id101, True, False)
+                add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id101, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+                groups.put(L2gid)
+
+            msg = add_l2_flood_group(self.controller, tmp_ports1, vlan_id101, vlan_id101)
+            groups.put(msg.group_id)
+            add_bridge_flow(self.controller, None, vlan_id101, msg.group_id, True)
+
+            # do_barrier(self.controller)
+
+            logging.info(
+                "Add a flow to TABLE-60 to match vlan {} and action Send to Controller".format(vlan_id101))
+            add_acl_rule(self.controller, vlan_id=vlan_id101)
+
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.vlan_vid(vlan_id101))
+
+            # Create VLAN102 flow and tables for port3 and port4
+            tmp_ports2 = list(ports)
+            tmp_ports2.remove(ports[0])
+            tmp_ports2.remove(ports[1])
+
+            for port in tmp_ports2:
+                L2gid, l2msg = add_one_l2_interface_group(self.controller, port, vlan_id102, True, False)
+                add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id102, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+                groups.put(L2gid)
+
+            msg = add_l2_flood_group(self.controller, tmp_ports2, vlan_id102, vlan_id102)
+            groups.put(msg.group_id)
+            add_bridge_flow(self.controller, None, vlan_id102, msg.group_id, True)
+
+            # do_barrier(self.controller)
+
+            logging.info(
+                "Add a flow to TABLE-60 to match vlan {} and action Send to Controller".format(vlan_id102))
+            add_acl_rule(self.controller, vlan_id=vlan_id102)
+
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.vlan_vid(vlan_id102))
+
+
+            # verify flood VLAN100 from port1 to port4
+            logging.info("Creating a double tagged vlan packet with outer vlan id {}".format(vlan_id100))
+            for ofport in tmp_ports:
+                # change dest based on port number
+                mac_src = '00:12:34:56:78:%02X' % ofport
+                parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
+                                                        out_vlan_vid=vlan_id100, in_dl_vlan_enable=True, in_vlan_vid=10,
+                                                        eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+                pkt = str(parsed_pkt)
+                self.dataplane.send(ofport, pkt)
+                # self won't rx packet
+                verify_no_packet(self, pkt, ofport)
+                # others will rx packet
+                tmp_ports.remove(ofport)
+                verify_packets(self, pkt, tmp_ports)
+
+                # verify flood VLAN101 from port2 to port4
+                logging.info("Creating a double tagged vlan packet with outer vlan id {}".format(vlan_id101))
+                for ofport in tmp_ports1:
+                    # change dest based on port number
+                    mac_src = '00:12:34:56:78:%02X' % ofport
+                    parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
+                                                            out_vlan_vid=vlan_id101, in_dl_vlan_enable=True,
+                                                            in_vlan_vid=10,
+                                                            eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+                    pkt = str(parsed_pkt)
+                    self.dataplane.send(ofport, pkt)
+                    # self won't rx packet
+                    verify_no_packet(self, pkt, ofport)
+                    # others will rx packet
+                    tmp_ports1.remove(ofport)
+                    verify_packets(self, pkt, tmp_ports1)
+
+                    # verify flood VLAN102 from port3 to port4
+                    logging.info("Creating a double tagged vlan packet with outer vlan id {}".format(vlan_id102))
+                    for ofport in tmp_ports2:
+                        # change dest based on port number
+                        mac_src = '00:12:34:56:78:%02X' % ofport
+                        parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
+                                                                out_vlan_vid=vlan_id102, in_dl_vlan_enable=True,
+                                                                in_vlan_vid=10,
+                                                                eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+                        pkt = str(parsed_pkt)
+                        self.dataplane.send(ofport, pkt)
+                        # self won't rx packet
+                        verify_no_packet(self, pkt, ofport)
+                        # others will rx packet
+                        tmp_ports2.remove(ofport)
+                        verify_packets(self, pkt, tmp_ports2)
+
+                        # verify flood VLAN101 to port1 - no receive on other ports
+                        logging.info("Creating a double tagged vlan packet with outer vlan id {}".format(vlan_id101))
+                        mac_src = '00:12:34:56:78:01'
+                        parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
+                                                                    out_vlan_vid=vlan_id101, in_dl_vlan_enable=True,
+                                                                    in_vlan_vid=10,
+                                                                    eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+                        pkt = str(parsed_pkt)
+                        self.dataplane.send(ports[0], pkt)
+                        # won't rx packet
+                        verify_no_packet(self, pkt, ports[1])
+                        verify_no_packet(self, pkt, ports[2])
+                        verify_no_packet(self, pkt, ports[3])
+
+                        # verify flood VLAN100 to port4 - receive on port1
+                        logging.info("Creating a double tagged vlan packet with outer vlan id {}".format(vlan_id100))
+                        mac_src = '00:12:34:56:78:04'
+                        parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
+                                                                out_vlan_vid=vlan_id100, in_dl_vlan_enable=True,
+                                                                in_vlan_vid=10,
+                                                                eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+                        pkt = str(parsed_pkt)
+                        self.dataplane.send(ports[3], pkt)
+                        tmp_ports = list(ports)
+                        tmp_ports.remove(ports[1])
+                        tmp_ports.remove(ports[2])
+                        tmp_ports.remove(ports[3])
+                        # rx packet on port1
+                        verify_packets(self, pkt, tmp_ports)
+
+                        # verify flood VLAN101 to port4 - receive on port2
+                        logging.info("Creating a double tagged vlan packet with outer vlan id {}".format(vlan_id101))
+                        mac_src = '00:12:34:56:78:04'
+                        parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
+                                                                out_vlan_vid=vlan_id101, in_dl_vlan_enable=True,
+                                                                in_vlan_vid=10,
+                                                                eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+                        pkt = str(parsed_pkt)
+                        self.dataplane.send(ports[3], pkt)
+                        tmp_ports = list(ports)
+                        tmp_ports.remove(ports[0])
+                        tmp_ports.remove(ports[2])
+                        tmp_ports.remove(ports[3])
+                        # rx packet on port1
+                        verify_packets(self, pkt, tmp_ports)
+
+                        # verify flood VLAN102 to port4 - receive on port3
+                        logging.info("Creating a double tagged vlan packet with outer vlan id {}".format(vlan_id102))
+                        mac_src = '00:12:34:56:78:04'
+                        parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
+                                                                out_vlan_vid=vlan_id102, in_dl_vlan_enable=True,
+                                                                in_vlan_vid=10,
+                                                                eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+                        pkt = str(parsed_pkt)
+                        self.dataplane.send(ports[3], pkt)
+                        tmp_ports = list(ports)
+                        tmp_ports.remove(ports[0])
+                        tmp_ports.remove(ports[1])
+                        tmp_ports.remove(ports[3])
+                        # rx packet on port1
+                        verify_packets(self, pkt, tmp_ports)
+
+                        logging.info("Cleanup flows")
+                        delete_all_flows(self.controller)
+
+                        # verify flood VLAN101 to port1 and port4 - no receive on any ports
+                        logging.info("Creating a double tagged vlan packet with outer vlan id {}".format(vlan_id100))
+                        mac_src = '00:12:34:56:78:01'
+                        parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
+                                                                out_vlan_vid=vlan_id100, in_dl_vlan_enable=True,
+                                                                in_vlan_vid=10,
+                                                                eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+                        pkt = str(parsed_pkt)
+                        self.dataplane.send(ports[0], pkt)
+                        tmp_ports = list(ports)
+                        tmp_ports.remove(ports[0])
+                        # won't rx packet
+                        verify_no_packet(self, pkt, ports[1])
+                        verify_no_packet(self, pkt, ports[2])
+                        verify_no_packet(self, pkt, ports[3])
+
+                        logging.info("Creating a double tagged vlan packet with outer vlan id {}".format(vlan_id100))
+                        mac_src = '00:12:34:56:78:04'
+                        parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
+                                                                out_vlan_vid=vlan_id100, in_dl_vlan_enable=True,
+                                                                in_vlan_vid=10,
+                                                                eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+                        pkt = str(parsed_pkt)
+                        self.dataplane.send(ports[3], pkt)
+                        tmp_ports = list(ports)
+                        tmp_ports.remove(ports[3])
+                        # won't rx packet
+                        verify_no_packet(self, pkt, ports[0])
+                        verify_no_packet(self, pkt, ports[1])
+                        verify_no_packet(self, pkt, ports[2])
+
+        finally:
+            delete_all_flows(self.controller)
+            delete_groups(self.controller, groups)
+            delete_all_groups(self.controller)
+            logging.info("End of Test")
+
+
+class FabricSW_OF_Counters_TC_0095(base_tests.SimpleDataPlane):
+    """
+    To verify the following port counters can be retrieved successfully from Open Flow switch:
+    rx_bytes_total, tx_bytes_total, rx_packets_total, tx_packets_total, rx_drop_packets_total, tx_drop_packets_total.
+    """
+
+    def runTest(self):
+        groups = Queue.LifoQueue()
+        try:
+            ports = sorted(config["port_map"].keys())
+            vlan_id = 100
+            vlan_len = 4
+            num_pkts = 5
+            pktlen = 108
+            rx_bytes_expected = (pktlen + vlan_len) * num_pkts
+            rx_dropped_expected = 0
+            tx_pkt_expected = num_pkts
+            tx_bytes_expected = rx_bytes_expected
+            tx_dropped_expected = 0
+
+            for port in ports:
+                L2gid, l2msg = add_one_l2_interface_group(self.controller, port, vlan_id, True, False)
+                add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+                groups.put(L2gid)
+
+            msg = add_l2_flood_group(self.controller, ports, vlan_id, vlan_id)
+            groups.put(msg.group_id)
+            add_bridge_flow(self.controller, None, vlan_id, msg.group_id, True)
+
+            # do_barrier(self.controller)
+
+            logging.info("Add a flow to TABLE-60 to match vlan {}".format(vlan_id))
+            add_acl_rule(self.controller, vlan_id=vlan_id)
+
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.vlan_vid(vlan_id))
+
+            # Send Port_Stats request for the ingress port (retrieve old counter state)
+            initial_stats_rx = get_port_stats(self, ports[0])
+            initial_stats_tx = get_port_stats(self, ports[1])
+
+            logging.info("Get required counter values from port".format(ports[0]))
+            rx_bytes_before = get_required_statistic_from_port(self, ports[0], "rx_bytes")
+            rx_pkts_before = get_required_statistic_from_port(self, ports[0], "rx_packets")
+            rx_dropped_before = get_required_statistic_from_port(self, ports[0], "rx_dropped")
+            tx_bytes_before = get_required_statistic_from_port(self, ports[1], "tx_bytes")
+            tx_packets_before = get_required_statistic_from_port(self, ports[1], "tx_packets")
+            tx_dropped_before = get_required_statistic_from_port(self, ports[1], "tx_dropped")
+
+            logging.info("Creating a double tagged vlan packet with outer vlan id {}".format(vlan_id))
+            parsed_pkt = simple_tcp_packet_two_vlan(pktlen=pktlen,
+                                                    out_dl_vlan_enable=True,
+                                                    out_vlan_vid=vlan_id,
+                                                    in_dl_vlan_enable=True,
+                                                    in_vlan_vid=10,
+                                                    eth_dst='00:12:34:56:78:9a')
+            pkt = str(parsed_pkt)
+
+            logging.info("Send double tugged packets to port {}".format(ports[0]))
+            for pkt_cnt in range(num_pkts):
+                self.dataplane.send(ports[0], pkt)
+
+            logging.info("Verify transmitted_packet counters")
+            verify_port_stats(self, ports[0], initial=initial_stats_rx, rx_pkts=num_pkts)
+            verify_port_stats(self, ports[1], initial=initial_stats_tx, tx_pkts=num_pkts)
+
+            logging.info("Get required counter values from port after sending packets".format(ports[0]))
+            rx_bytes_after = get_required_statistic_from_port(self, ports[0], "rx_bytes")
+            rx_pkts_after = get_required_statistic_from_port(self, ports[0], "rx_packets")
+            rx_dropped_after = get_required_statistic_from_port(self, ports[0], "rx_dropped")
+            tx_bytes_after = get_required_statistic_from_port(self, ports[1], "tx_bytes")
+            tx_packets_after = get_required_statistic_from_port(self, ports[1], "tx_packets")
+            tx_dropped_after = get_required_statistic_from_port(self, ports[1], "tx_dropped")
+
+            logging.info("Verify values incremented as expected on port".format(ports[0]))
+            self.assertGreaterEqual(rx_pkts_after - rx_pkts_before, num_pkts,
+                                    "Port RX packet counter is not updated as expected: {}, current value: {}".format(num_pkts, rx_pkts_after - rx_pkts_before))
+            self.assertGreaterEqual(rx_bytes_after - rx_bytes_before, rx_bytes_expected,
+                                    "Port RX bytes counter is not updated as expected: {}, current value: {}".format(rx_bytes_expected, rx_bytes_after - rx_bytes_before))
+            self.assertGreaterEqual(rx_dropped_after - rx_dropped_before, rx_dropped_expected,
+                             "Port RX dropped counter is not updated as expected: {}, current value: {}".format(rx_dropped_expected, rx_dropped_after - rx_dropped_before))
+
+            self.assertEqual(tx_packets_after - tx_packets_before, tx_pkt_expected,
+                            "Port TX packet counter is not updated as expected: {}, current value: {}".format(tx_pkt_expected, tx_packets_after - tx_packets_before))
+            self.assertEqual(tx_bytes_after - tx_bytes_before, tx_bytes_expected,
+                            "Port TX bytes counter is not updated as expected: {}, current value: {}".format(tx_bytes_expected, tx_bytes_after - tx_bytes_before))
+            self.assertEqual(tx_dropped_after - tx_dropped_before, tx_dropped_expected,
+                             "Port TX dropped counter is not updated as expected: {}, current value: {}".format(tx_dropped_expected, tx_dropped_after - tx_dropped_before))
+
+        finally:
+            delete_all_flows(self.controller)
+            delete_groups(self.controller, groups)
+            delete_all_groups(self.controller)
+            logging.info("End of Test")
+
+
+def similar_steps(eth_type, not_expected_eth_type, self):
+    """
+        Similar steps for tests: FabricSW_OF_BDDP_TC_0020 and FabricSW_OF_LLDP_TC_0015
+        parameters:
+        @param eth_type matched ethernet type
+        @param not_expected_eth_type not matched ethernet type
+        @param self class instance
+    """
+
+    ports = sorted(config["port_map"].keys())
+
+    logging.info("Step 1")
+    logging.info(
+        "Add a flow to TABLE-60 to match Ethernet Type to {} and action Send to Controller".format(eth_type))
+    add_acl_rule(self.controller, eth_type=eth_type)
+
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+
+    logging.info("Step 2")
+    logging.info("Creating an untagged packet with ethernet type {}".format(hex(eth_type)))
+    parsed_pkt = simple_eth_packet(eth_type=eth_type)
+    eth_pkt = str(parsed_pkt)
+
+    logging.info("Step 3")
+    logging.info("Creating an untagged packet with ethernet type {}".format(hex(not_expected_eth_type)))
+    parsed_pkt_not_expected = simple_eth_packet(eth_type=not_expected_eth_type)
+    eth_pkt_non_lldp = str(parsed_pkt_not_expected)
+
+    logging.info("Step 4")
+    logging.info(
+        "Send  untagged packet with ethernet type {} to port {}".format(hex(eth_type), ports[0]))
+    self.dataplane.send(ports[0], eth_pkt)
+    verify_packet_in(self, eth_pkt, ports[0], ofp.OFPR_ACTION)
+
+    logging.info("Step 5")
+    logging.info(
+        "Send  untagged packet with ethernet type {} to port {}".format(hex(not_expected_eth_type), ports[0]))
+    self.dataplane.send(ports[0], eth_pkt_non_lldp)
+    verify_no_packet_in(self, eth_pkt_non_lldp, ports[0])
+
+    logging.info("Step 6 Cleanup flows")
+    delete_all_flows(self.controller)
+    time.sleep(1)
+
+    logging.info("Step 7")
+    logging.info(
+        "Send  untagged packet with ethernet type {} to port {}".format(hex(eth_type), ports[0]))
+    self.dataplane.send(ports[0], eth_pkt)
+    verify_no_packet_in(self, eth_pkt, ports[0])
+
+
+@disabled
+class test_interface_flap(base_tests.SimpleDataPlane):
+    """
+    This is pilot test case to verify interface flap
+    """
+
+    def runTest(self):
+        try:
+            eth_type_eapol = 0x888e
+            eth_type = 0x8100
+            vlan_id100 = 100
+            vlanid200 = 200
+
+            logging.info("Step 1")
+            logging.info(
+                "Add a flow to TABLE-10 to match VLAN ID '100' for packets received at Data Port 1 and action transition to TABLE-20.")
+
+            ports = sorted(config["port_map"].keys())
+            for port in ports:
+                add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id100, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+
+            add_acl_rule(self.controller, eth_type=eth_type_eapol)
+
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.eth_type(eth_type_eapol))
+
+            logging.info("Step 2")
+            logging.info("Creating a double tagged vlan packet with ethernet type {}".format(hex(eth_type_eapol)))
+            parsed_pkt = simple_ether_packet_two_vlan(out_dl_vlan_enable=True,
+                                                      in_dl_vlan_enable=True,
+                                                      out_vlan_tpid=eth_type,
+                                                      in_vlan_tpid=eth_type_eapol,
+                                                      out_vlan_vid=vlan_id100,
+                                                      in_vlan_vid=vlanid200)
+            vlan_pkt = str(parsed_pkt)
+
+            logging.info("Step 4")
+            logging.info("Send untagged packet to port {}".format(ports[0]))
+
+            self.dataplane.send(ports[0], vlan_pkt)
+            verify_packet_in(self, vlan_pkt, ports[0], ofp.OFPR_ACTION)
+
+            print("")
+            print("flapping interface")
+            self.dataplane.port_down(ports[0])
+
+            time.sleep(2)
+
+            print("bring up interface")
+            self.dataplane.port_up(ports[0])
+
+            self.dataplane.send(ports[0], vlan_pkt)
+            verify_packet_in(self, vlan_pkt, ports[0], ofp.OFPR_ACTION)
+
+
+        finally:
+            delete_all_flows(self.controller)
+            delete_all_groups(self.controller)
+            logging.info("End of Test")
diff --git a/Fabric/Tests/oft b/Fabric/Tests/oft
new file mode 100755
index 0000000..cae63b6
--- /dev/null
+++ b/Fabric/Tests/oft
@@ -0,0 +1,619 @@
+#!/usr/bin/env python
+"""
+@package oft
+
+OpenFlow test framework top level script
+
+This script is the entry point for running OpenFlow tests using the OFT
+framework. For usage information, see --help or the README.
+
+To add a new command line option, edit both the CONFIG_DEFAULT dictionary and
+the config_setup function. The option's result will end up in the global
+oftest.config dictionary.
+"""
+
+from __future__ import print_function
+
+import sys
+import optparse
+import logging
+import unittest
+import time
+import os
+import imp
+import random
+import signal
+import fnmatch
+import copy
+
+ROOT_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)
+LOG_DIR = os.path.join(ROOT_DIR, "Log")+time.strftime("/%Y-%m/%d%H%M%S")
+#LOG_FILE = time.strftime("%H%M%S")+"oft.log"
+PY_SRC_DIR = os.path.join(ROOT_DIR, 'Utilities', 'src', 'python')
+if os.path.exists(os.path.join(PY_SRC_DIR, 'oftest')):
+    # Running from source tree
+    sys.path.insert(0, PY_SRC_DIR)
+
+if os.path.exists(os.path.join(ROOT_DIR, 'Utilities', 'accton')):
+    PY_ACCTON_DIR = os.path.join(ROOT_DIR, 'Utilities', 'accton')
+    sys.path.insert(0, PY_ACCTON_DIR)
+    
+import oftest
+from oftest import config
+import oftest.ofutils
+import oftest.help_formatter
+import loxi
+
+##@var DEBUG_LEVELS
+# Map from strings to debugging levels
+DEBUG_LEVELS = {
+    'debug'              : logging.DEBUG,
+    'verbose'            : logging.DEBUG,
+    'info'               : logging.INFO,
+    'warning'            : logging.WARNING,
+    'warn'               : logging.WARNING,
+    'error'              : logging.ERROR,
+    'critical'           : logging.CRITICAL
+}
+
+##@var CONFIG_DEFAULT
+# The default configuration dictionary for OFT
+CONFIG_DEFAULT = {
+    # Miscellaneous options
+    "list"               : False,
+    "list_test_names"    : False,
+    "allow_user"         : False,
+
+    # Test selection options
+    "test_spec"          : "",
+    "test_file"          : None,
+    "test_dir"           : os.path.join(ROOT_DIR, "Tests"),
+
+    # Switch connection options
+    "controller_host"    : "0.0.0.0",  # For passive bind
+    "controller_port"    : 6653,
+    "switch_ip"          : None,  # If not none, actively connect to switch
+    "switch_type"          : None,  # If not none, adapt flows to pipeline differences for switch type
+    "platform"           : "eth",
+    "platform_args"      : None,
+    "platform_dir"       : os.path.join(ROOT_DIR, "Utilities", "platforms"),
+    "interfaces"         : [],
+    "openflow_version"   : "1.0",
+
+    # Logging options
+    "log_file"           : time.strftime("%H%M%S")+"oft.log",
+    "log_dir"            : LOG_DIR,
+    "debug"              : "verbose",
+    "profile"            : False,
+    "profile_file"       : "profile.out",
+    "xunit"              : False,
+    "xunit_dir"          : "xunit",
+
+    # Test behavior options
+    "relax"              : False,
+    "test_params"        : "None",
+    "fail_skipped"       : False,
+    "default_timeout"    : 2.0,
+    "default_negative_timeout" : 0.01,
+    "minsize"            : 0,
+    "random_seed"        : None,
+    "disable_ipv6"       : False,
+    "random_order"       : False,
+    "dump_packet"        : True,
+    "cicada_poject"      : False,
+    "force_ofdpa_restart": False,
+    # Other configuration
+    "port_map"           : {},
+}
+
+def config_setup():
+    """
+    Set up the configuration including parsing the arguments
+
+    @return A pair (config, args) where config is an config
+    object and args is any additional arguments from the command line
+    """
+
+    usage = "usage: %prog [options] (test|group)..."
+
+    description = """\
+OFTest is a framework and set of tests for validating OpenFlow switches.
+
+The default configuration assumes that an OpenFlow 1.0 switch is attempting to
+connect to a controller on the machine running OFTest, port 6653. Additionally,
+the interfaces veth1, veth3, veth5, and veth7 should be connected to the switch's
+dataplane.
+
+If no positional arguments are given then OFTest will run all tests that
+depend only on standard OpenFlow 1.0. Otherwise each positional argument
+is interpreted as either a test name or a test group name. The union of
+these will be executed. To see what groups each test belongs to use the
+--list option. Tests and groups can be subtracted from the result by
+prefixing them with the '^' character.
+"""
+
+    # Parse --interface
+    def check_interface(option, opt, value):
+        try:
+            ofport, interface = value.split('@', 1)
+            ofport = int(ofport)
+        except ValueError:
+            raise optparse.OptionValueError("incorrect interface syntax (got %s, expected 'ofport@interface')" % repr(value))
+        return (ofport, interface)
+
+    class Option(optparse.Option):
+        TYPES = optparse.Option.TYPES + ("interface",)
+        TYPE_CHECKER = copy.copy(optparse.Option.TYPE_CHECKER)
+        TYPE_CHECKER["interface"] = check_interface
+
+    parser = optparse.OptionParser(version="%prog 0.1",
+                                   usage=usage,
+                                   description=description,
+                                   formatter=oftest.help_formatter.HelpFormatter(),
+                                   option_class=Option)
+
+    # Set up default values
+    parser.set_defaults(**CONFIG_DEFAULT)
+
+    parser.add_option("--list", action="store_true",
+                      help="List all tests and exit")
+    parser.add_option("--list-test-names", action='store_true',
+                      help="List test names matching the test spec and exit")
+    parser.add_option("--allow-user", action="store_true",
+                      help="Proceed even if oftest is not run as root")
+
+    group = optparse.OptionGroup(parser, "Test selection options")
+    group.add_option("-T", "--test-spec", "--test-list", help="Tests to run, separated by commas")
+    group.add_option("-f", "--test-file", help="File of tests to run, one per line")
+    group.add_option("--test-dir", type="string", help="Directory containing tests")
+    parser.add_option_group(group)
+
+    group = optparse.OptionGroup(parser, "Switch connection options")
+    group.add_option("-H", "--host", dest="controller_host",
+                      help="IP address to listen on (default %default)")
+    group.add_option("-p", "--port", dest="controller_port",
+                      type="int", help="Port number to listen on (default %default)")
+    group.add_option("-S", "--switch-ip", dest="switch_ip",
+                      help="If set, actively connect to this switch by IP")
+    group.add_option("-Y", "--switch-type", dest="switch_type",
+                      help="If set to qmx, flows will adapt to pipline differences")
+    group.add_option("-P", "--platform", help="Platform module name (default %default)")
+    group.add_option("-a", "--platform-args", help="Custom arguments for the platform")
+    group.add_option("--platform-dir", type="string", help="Directory containing platform modules")
+    group.add_option("--interface", "-i", type="interface", dest="interfaces", metavar="INTERFACE", action="append",
+                     help="Specify a OpenFlow port number and the dataplane interface to use. May be given multiple times. Example: 1@eth1")
+    group.add_option("--of-version", "-V", dest="openflow_version", choices=loxi.version_names.values(),
+                     help="OpenFlow version to use")
+    parser.add_option_group(group)
+
+    group = optparse.OptionGroup(parser, "Logging options")
+    group.add_option("--log-file", help="Name of log file (default %default)")
+    group.add_option("--log-dir", help="Name of log directory")
+    dbg_lvl_names = sorted(DEBUG_LEVELS.keys(), key=lambda x: DEBUG_LEVELS[x])
+    group.add_option("--debug", choices=dbg_lvl_names,
+                      help="Debug lvl: debug, info, warning, error, critical (default %default)")
+    group.add_option("-v", "--verbose", action="store_const", dest="debug",
+                     const="verbose", help="Shortcut for --debug=verbose")
+    group.add_option("-q", "--quiet", action="store_const", dest="debug",
+                     const="warning", help="Shortcut for --debug=warning")
+    group.add_option("--profile", action="store_true", help="Enable Python profiling")
+    group.add_option("--profile-file", help="Output file for Python profiler")
+    group.add_option("--xunit", action="store_true", help="Enable xUnit-formatted results")
+    group.add_option("--xunit-dir", help="Output directory for xUnit-formatted results")
+    parser.add_option_group(group)
+
+    group = optparse.OptionGroup(parser, "Test behavior options")
+    group.add_option("--relax", action="store_true",
+                      help="Relax packet match checks allowing other packets")
+    test_params_help = """Set test parameters: key=val;... (see --list)
+    """
+    group.add_option("-t", "--test-params", help=test_params_help)
+    group.add_option("--fail-skipped", action="store_true",
+                      help="Return failure if any test was skipped")
+    group.add_option("--default-timeout", type=float,
+                      help="Timeout in seconds for most operations")
+    group.add_option("--default-negative-timeout", type=float,
+                      help="Timeout in seconds for negative checks")
+    group.add_option("--minsize", type="int",
+                      help="Minimum allowable packet size on the dataplane.")
+    group.add_option("--random-seed", type="int",
+                      help="Random number generator seed")
+    group.add_option("--force-ofdpa-restart",
+                     help="If set force ofdpa restart on user@switchIP")
+    group.add_option("--disable-ipv6", action="store_true",
+                      help="Disable IPv6 tests")
+    group.add_option("--random-order", action="store_true",
+                      help="Randomize order of tests")
+    group.add_option("--dump_packet", action="store_true",
+                      help="Dump packet content on log when verify packet fail")
+    group.add_option("--cicada_poject", action="store_true",
+                      help="True verify Cicada behavior, False verify AOS behaviro")
+    parser.add_option_group(group)
+
+    # Might need this if other parsers want command line
+    # parser.allow_interspersed_args = False
+    (options, args) = parser.parse_args()
+
+    # If --test-dir wasn't given, pick one based on the OpenFlow version
+#    if options.test_dir == None:
+#        if options.openflow_version == "1.3":
+#            options.test_dir = os.path.join(ROOT_DIR, "Test", "ofdpa")
+
+    # Convert options from a Namespace to a plain dictionary
+    config = CONFIG_DEFAULT.copy()
+    for key in config.keys():
+        config[key] = getattr(options, key)
+
+    return (config, args)
+
+#def logging_directory()
+    """
+    creates a specific log directory based on day of execution
+    """
+#    log_dir=os.path.join(ROOT_DIR, "Log")+time.strftime("/%Y/%m/%d")
+#    return(log_dir)
+
+def logging_setup(config):
+    """
+    Set up logging based on config
+    """
+
+    logging.getLogger().setLevel(DEBUG_LEVELS[config["debug"]])
+
+    if config["log_dir"] != None:
+        if not os.path.exists(config["log_dir"]):
+            os.makedirs(config["log_dir"])
+    else:
+        if os.path.exists(config["log_file"]):
+            os.remove(config["log_file"])
+
+    oftest.open_logfile('main')
+
+def xunit_setup(config):
+    """
+    Set up xUnit output based on config
+    """
+
+    if not config["xunit"]:
+        return
+
+    if os.path.exists(config["xunit_dir"]):
+        import shutil
+        shutil.rmtree(config["xunit_dir"])
+    os.makedirs(config["xunit_dir"])
+
+def pcap_setup(config):
+    """
+    Set up dataplane packet capturing based on config
+    """
+
+    if config["log_dir"] == None:
+        filename = os.path.splitext(config["log_file"])[0] + '.pcap'
+        oftest.dataplane_instance.start_pcap(filename)
+    else:
+        # start_pcap is called per-test in base_tests
+        pass
+
+def profiler_setup(config):
+    """
+    Set up profiler based on config
+    """
+
+    if not config["profile"]:
+        return
+
+    import cProfile
+    profiler = cProfile.Profile()
+    profiler.enable()
+
+    return profiler
+
+def profiler_teardown(profiler):
+    """
+    Tear down profiler based on config
+    """
+
+    if not config["profile"]:
+        return
+
+    profiler.disable()
+    profiler.dump_stats(config["profile_file"])
+
+
+def load_test_modules(config):
+    """
+    Load tests from the test_dir directory.
+
+    Test cases are subclasses of unittest.TestCase
+
+    Also updates the _groups member to include "standard" and
+    module test groups if appropriate.
+
+    @param config The oft configuration dictionary
+    @returns A dictionary from test module names to tuples of
+    (module, dictionary from test names to test classes).
+    """
+
+    result = {}
+
+    for root, dirs, filenames in os.walk(config["test_dir"]):
+        # Iterate over each python file
+        for filename in fnmatch.filter(filenames, '[!.]*.py'):
+            modname = os.path.splitext(os.path.basename(filename))[0]
+
+            try:
+                if sys.modules.has_key(modname):
+                    mod = sys.modules[modname]
+                else:
+                    mod = imp.load_module(modname, *imp.find_module(modname, [root]))
+            except:
+                logging.warning("Could not import file " + filename)
+                raise
+
+            # Find all testcases defined in the module
+            tests = dict((k, v) for (k, v) in mod.__dict__.items() if type(v) == type and
+                                                                      issubclass(v, unittest.TestCase) and
+                                                                      hasattr(v, "runTest"))
+            if tests:
+                for (testname, test) in tests.items():
+                    # Set default annotation values
+                    if not hasattr(test, "_groups"):
+                        test._groups = []
+                    if not hasattr(test, "_nonstandard"):
+                        test._nonstandard = False
+                    if not hasattr(test, "_disabled"):
+                        test._disabled = False
+
+                    # Put test in its module's test group
+                    if not test._disabled:
+                        test._groups.append(modname)
+
+                    # Put test in the standard test group
+                    if not test._disabled and not test._nonstandard:
+                        test._groups.append("standard")
+                        test._groups.append("all") # backwards compatibility
+
+                result[modname] = (mod, tests)
+
+    return result
+
+def prune_tests(test_specs, test_modules, version):
+    """
+    Return tests matching the given test-specs and OpenFlow version
+    @param test_specs A list of group names or test names.
+    @param version An OpenFlow version (e.g. "1.0")
+    @param test_modules Same format as the output of load_test_modules.
+    @returns Same format as the output of load_test_modules.
+    """
+    result = {}
+    for e in test_specs:
+        matched = False
+
+        if e.startswith('^'):
+            negated = True
+            e = e[1:]
+        else:
+            negated = False
+
+        for (modname, (mod, tests)) in test_modules.items():
+            for (testname, test) in tests.items():
+                if e in test._groups or e == "%s.%s" % (modname, testname):
+                    result.setdefault(modname, (mod, {}))
+                    if not negated:
+                        if not hasattr(test, "_versions") or version in test._versions:
+                            result[modname][1][testname] = test
+                    else:
+                        if modname in result and testname in result[modname][1]:
+                            del result[modname][1][testname]
+                            if not result[modname][1]:
+                                del result[modname]
+                    matched = True
+
+        if not matched:
+            die("test-spec element %s did not match any tests" % e)
+
+    return result
+
+def die(msg, exit_val=1):
+    logging.critical(msg)
+    sys.exit(exit_val)
+
+#
+# Main script
+#
+
+# Setup global configuration
+(new_config, args) = config_setup()
+oftest.config.update(new_config)
+
+logging_setup(config)
+xunit_setup(config)
+logging.info("++++++++ " + time.asctime() + " ++++++++")
+
+# Pick an OpenFlow protocol module based on the configured version
+name_to_version = dict((v,k) for k, v in loxi.version_names.iteritems())
+sys.modules["ofp"] = loxi.protocol(name_to_version[config["openflow_version"]])
+
+# HACK: testutils.py imports controller.py, which needs the ofp module
+import oftest.testutils
+
+# Allow tests to import each other
+sys.path.append(config["test_dir"])
+
+test_specs = args
+if config["test_spec"] != "":
+    logging.warning("The '--test-spec' option is deprecated.")
+    test_specs += config["test_spec"].split(',')
+if config["test_file"] != None:
+    with open(config["test_file"], 'r') as f:
+        for line in f:
+            line, _, _ = line.partition('#') # remove comments
+            line = line.strip()
+            if line:
+                test_specs.append(line)
+if test_specs == []:
+    test_specs = ["standard"]
+
+test_modules = load_test_modules(config)
+
+# Check if test list is requested; display and exit if so
+if config["list"]:
+    mod_count = 0
+    test_count = 0
+    all_groups = set()
+
+    print("""
+Tests are shown grouped by module. If a test is in any groups beyond
+"standard" and its module's group then they are shown in parentheses.
+
+Tests marked with '*' are non-standard and may require vendor extensions or
+special switch configuration. These are not part of the "standard" test group.
+
+Tests marked with '!' are disabled because they are experimental,
+special-purpose, or are too long to be run normally. These are not part of
+the "standard" test group or their module's test group.
+
+Tests marked (TP1) after name take --test-params including:
+
+    'vid=N;strip_vlan=bool;add_vlan=bool'
+
+Test List:
+""")
+    for (modname, (mod, tests)) in test_modules.items():
+        mod_count += 1
+        desc = (mod.__doc__ or "No description").strip().split('\n')[0]
+        print("  Module %13s: %s" % (mod.__name__, desc))
+
+        for (testname, test) in tests.items():
+            desc = (test.__doc__ or "No description").strip().split('\n')[0]
+
+            groups = set(test._groups) - set(["all", "standard", modname])
+            all_groups.update(test._groups)
+            if groups:
+                desc = "(%s) %s" % (",".join(groups), desc)
+            if hasattr(test, "_versions"):
+                desc = "(%s) %s" % (",".join(sorted(test._versions)), desc)
+
+            start_str = " %s%s %s:" % (test._nonstandard and "*" or " ",
+                                       test._disabled and "!" or " ",
+                                       testname)
+            print("  %22s : %s" % (start_str, desc))
+            test_count += 1
+        print
+    print("'%d' modules shown with a total of '%d' tests\n" %
+          (mod_count, test_count))
+    print("Test groups: %s" % (', '.join(sorted(all_groups))))
+
+    sys.exit(0)
+
+test_modules = prune_tests(test_specs, test_modules, config["openflow_version"])
+
+# Check if test list is requested; display and exit if so
+if config["list_test_names"]:
+    for (modname, (mod, tests)) in test_modules.items():
+        for (testname, test) in tests.items():
+            print("%s.%s" % (modname, testname))
+
+    sys.exit(0)
+
+# Generate the test suite
+#@todo Decide if multiple suites are ever needed
+suite = unittest.TestSuite()
+
+sorted_tests = []
+for (modname, (mod, tests)) in sorted(test_modules.items()):
+    for (testname, test) in sorted(tests.items()):
+        sorted_tests.append(test)
+
+if config["random_order"]:
+    random.shuffle(sorted_tests)
+
+for test in sorted_tests:
+    suite.addTest(test())
+
+# Allow platforms to import each other
+sys.path.append(config["platform_dir"])
+
+# Load the platform module
+platform_name = config["platform"]
+logging.info("Importing platform: " + platform_name)
+platform_mod = None
+try:
+    platform_mod = imp.load_module(platform_name, *imp.find_module(platform_name, [config["platform_dir"]]))
+except:
+    logging.warn("Failed to import " + platform_name + " platform module")
+    raise
+
+try:
+    platform_mod.platform_config_update(config)
+except:
+    logging.warn("Could not run platform host configuration")
+    raise
+
+if not config["port_map"]:
+    die("Interface port map was not defined by the platform. Exiting.")
+
+logging.debug("Configuration: " + str(config))
+logging.info("OF port map: " + str(config["port_map"]))
+
+oftest.ofutils.default_timeout = config["default_timeout"]
+oftest.ofutils.default_negative_timeout = config["default_negative_timeout"]
+oftest.testutils.MINSIZE = config['minsize']
+
+if os.getuid() != 0 and not config["allow_user"]:
+    die("Super-user privileges required. Please re-run with sudo or as root.")
+    sys.exit(1)
+
+if config["random_seed"] is not None:
+    logging.info("Random seed: %d" % config["random_seed"])
+    random.seed(config["random_seed"])
+else:
+    # Generate random seed and report to log file
+    seed = random.randrange(100000000)
+    logging.info("Autogen random seed: %d" % seed)
+    random.seed(seed)
+
+# Remove python's signal handler which raises KeyboardError. Exiting from an
+# exception waits for all threads to terminate which might not happen.
+signal.signal(signal.SIGINT, signal.SIG_DFL)
+
+if __name__ == "__main__":
+    profiler = profiler_setup(config)
+
+    # Set up the dataplane
+    oftest.dataplane_instance = oftest.dataplane.DataPlane(config)
+    pcap_setup(config)
+    for of_port, ifname in config["port_map"].items():
+        oftest.dataplane_instance.port_add(ifname, of_port)
+
+    logging.info("*** TEST RUN START: " + time.asctime())
+    if config["xunit"]:
+        try:
+            import xmlrunner  # fail-fast if module missing
+        except ImportError as ex:
+            oftest.dataplane_instance.kill()
+            profiler_teardown(profiler)
+            raise ex
+        runner = xmlrunner.XMLTestRunner(output=config["xunit_dir"],
+                                         outsuffix="",
+                                         verbosity=2)
+        result = runner.run(suite)
+    else:
+        result = unittest.TextTestRunner(verbosity=2).run(suite)
+    oftest.open_logfile('main')
+    if oftest.testutils.skipped_test_count > 0:
+        message = "Skipped %d test(s)" % oftest.testutils.skipped_test_count
+        logging.info(message)
+    logging.info("*** TEST RUN END  : %s", time.asctime())
+
+    # Shutdown the dataplane
+    oftest.dataplane_instance.kill()
+    oftest.dataplane_instance = None
+
+    profiler_teardown(profiler)
+
+    if result.failures or result.errors:
+        # exit(1) hangs sometimes
+        os._exit(1)
+    if oftest.testutils.skipped_test_count > 0 and config["fail_skipped"]:
+        os._exit(1)
diff --git a/Fabric/Tests/operational.py b/Fabric/Tests/operational.py
new file mode 100644
index 0000000..9292a08
--- /dev/null
+++ b/Fabric/Tests/operational.py
@@ -0,0 +1,15 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/Fabric/Tests/scalability.py b/Fabric/Tests/scalability.py
new file mode 100755
index 0000000..9292a08
--- /dev/null
+++ b/Fabric/Tests/scalability.py
@@ -0,0 +1,15 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/Fabric/Tests/seba-1.0.0 b/Fabric/Tests/seba-1.0.0
new file mode 100644
index 0000000..b478ec8
--- /dev/null
+++ b/Fabric/Tests/seba-1.0.0
@@ -0,0 +1,67 @@
+
+# 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.
+
+
+
+
+##########################################################################################
+###########################  CORD CERTIFICATION PROGRAM (CCP)   ########################## 
+##########################################################################################
+
+##############   This file lists the mandatory test cases to be executed  ################
+##################   for certifying a Fabric switch against SEBA1.0   ####################
+
+
+
+
+
+### Functional Test cases ###
+## Total #test cases - 19
+
+functional.FabricSW_OF_Bridging_TC_0001
+functional.FabricSW_OF_PacketInArp_TC_0005
+functional.FabricSW_OF_PacketInUDP_TC_0010
+functional.FabricSW_OF_L2FloodQinQ_TC_0015
+functional.FabricSW_OF_L2UnicastTagged_TC_0020
+functional.FabricSW_OF_EcmpGroupMod_TC_0025
+functional.FabricSW_OF_FloodGroupMod_TC_0030
+functional.FabricSW_OF_Mtu1500_TC_0035
+functional.FabricSW_OF__24ECMPL3_TC_0040
+functional.FabricSW_OF__24UcastTagged_TC_0045
+functional.FabricSW_OF__32ECMPL3_TC_0050
+functional.FabricSW_OF__32UcastTagged_TC_0055
+functional.FabricSW_OF_EAPOL_TC_0060
+functional.FabricSW_OF_ARP_TC_0065
+functional.FabricSW_OF_VLANPUSH_TC_0070
+functional.FabricSW_OF_LLDP_TC_0075
+functional.FabricSW_OF_BDDP_TC_0080
+functional.FabricSW_OF_VLANXConnect_Single_TC_0085
+#functional.FabricSW_OF_VLANXConnect_Multi_TC_0090
+#functional.FabricSW_OF_Counters_TC_0095
+
+
+
+### Operational Test cases ###
+## Total #test cases - 
+
+
+
+
+
+
+
+
+### Scalability Test cases ###
+## Total #test cases - 
diff --git a/Fabric/Utilities/accton/accton_util.py b/Fabric/Utilities/accton/accton_util.py
new file mode 100755
index 0000000..0f32e76
--- /dev/null
+++ b/Fabric/Utilities/accton/accton_util.py
@@ -0,0 +1,2210 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging
+
+from oftest import config
+import oftest.base_tests as base_tests
+import ofp
+import time
+from oftest.testutils import *
+from oftest.parse import parse_ipv6
+
+from ncclient import manager
+import ncclient
+
+OFDPA_GROUP_TYPE_SHIFT=28
+OFDPA_VLAN_ID_SHIFT   =16
+OFDPA_TUNNEL_ID_SHIFT =12
+OFDPA_TUNNEL_SUBTYPE_SHIFT=10
+
+#VLAN_TABLE_FLAGS
+VLAN_TABLE_FLAG_ONLY_UNTAG=1
+VLAN_TABLE_FLAG_ONLY_TAG  =2
+VLAN_TABLE_FLAG_ONLY_BOTH =3
+VLAN_TABLE_FLAG_ONLY_STACKED=5
+VLAN_TABLE_FLAG_PRIORITY=6
+VLAN_TABLE_FLAG_ONLY_UNTAG_PRIORITY=7
+VLAN_TABLE_FLAG_ONLY_POP_VLAN=8
+
+PORT_FLOW_TABLE=0
+VLAN_FLOW_TABLE=10
+VLAN_1_FLOW_TABLE=11
+MPLS_L2_PORT_FLOW_TABLE=13
+MPLS_L2_PORT_DSCP_TRUST_FLOW_TABLE=15
+MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE=16
+TERMINATION_FLOW_TABLE=20
+MPLS_TYPE_FLOW_TABLE=29
+UCAST_ROUTING_FLOW_TABLE=30
+MCAST_ROUTING_FLOW_TABLE=40
+BRIDGE_FLOW_TABLE=50
+ACL_FLOW_TABLE=60
+EGRESS_TPID_FLOW_TABLE = 235
+
+ONF_EXPERIMENTER_ID = 0x4F4E4600
+
+EGRESS_VLAN_FLOW_TABLE=210
+EGRESS_VLAN_1_FLOW_TABLE=211
+EGRESS_MAINTENANCE_POINT_FLOW_TABLE=226
+EGRESS_DSCP_TABLE=230
+EGRESS_TPID_TABLE=235
+EGRESS_SOURCE_MAC_LEARNING_TABLE=254
+
+def convertIP4toStr(ip_addr):
+    a=(ip_addr&0xff000000)>>24
+    b=(ip_addr&0x00ff0000)>>16
+    c=(ip_addr&0x0000ff00)>>8
+    d=(ip_addr&0x000000ff)
+    return str(a)+"."+str(b)+"."+str(c)+"."+str(d)
+
+def convertMACtoStr(mac):
+    if not isinstance(mac, list):
+        assert(0)
+
+    return ':'.join(['%02X' % x for x in mac])
+
+def getSwitchCpuMACFromDPID(dpid):
+    str_datapath_id_f= "{:016x}".format(dpid)
+    str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
+    switch_cpu_mac_str=str_datapath_id[6:]
+    switch_cpu_mac = switch_cpu_mac_str.split(":")
+    switch_cpu_mac=[int(switch_cpu_mac[i],16) for i in range(0, len(switch_cpu_mac))]
+
+    return switch_cpu_mac_str, switch_cpu_mac
+
+def DumpGroup(stats, verify_group_stats, always_show=True):
+    if(len(stats) > len(verify_group_stats)):
+        min_len = len(verify_group_stats)
+        print "Stats Len is not the same, stats>verify_group_stats"
+    if(len(stats)< len(verify_group_stats)):
+        min_len = len(stats)
+        print "Stats Len is not the same, stats<verify_group_stats"
+    else:
+        min_len = len(stats)
+
+    print "\r\n"
+    for i in range(min_len):
+        gs = stats[i]
+        gv = verify_group_stats[i]
+        print "FromSwtich:(GID=%lx, TYPE=%lx)\r\nVerify    :(GID=%lx, TYPE=%lx)"%(gs.group_id, gs.group_type, gv.group_id, gv.group_type)
+        if(len(gs.buckets) != len(gv.buckets)):
+            print "buckets len is not the same gs %lx, gv %lx",(len(gs.buckets), len(gv.buckets))
+
+        for j in range(len(gs.buckets)):
+           b1=gs.buckets[j]
+           b2=gv.buckets[j]
+           if(len(b1.actions) != len(b2.actions)):
+               print "action len is not the same"
+
+           for k in range(len(b1.actions)):
+               a1=b1.actions[k]
+               a2=b2.actions[k]
+               if(always_show == True):
+                   print "a1:"+a1.show()
+                   print "a2:"+a2.show()
+
+def AssertGroup(self, stats, verify_group_stats):
+    self.assertTrue(len(stats) ==len(verify_group_stats), "stats len is not the same")
+
+    for i in range(len(stats)):
+        gs = stats[i]
+        gv = verify_group_stats[i]
+        self.assertTrue(len(gs.buckets) == len(gv.buckets), "buckets len is not the same")
+
+        for j in range(len(gs.buckets)):
+           b1=gs.buckets[j]
+           b2=gv.buckets[j]
+           self.assertTrue(len(b1.actions) == len(b2.actions), "action len is not the same")
+
+           for k in range(len(b1.actions)):
+               a1=b1.actions[k]
+               a2=b2.actions[k]
+               self.assertEquals(a1, a2, "action is not the same")
+
+def encode_l2_interface_group_id(vlan, id):
+    return id + (vlan << OFDPA_VLAN_ID_SHIFT)
+
+def encode_l2_rewrite_group_id(id):
+    return id + (1 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l3_unicast_group_id(id):
+    return id + (2 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l2_mcast_group_id(vlan, id):
+    return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (3 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l2_flood_group_id(vlan, id):
+    return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (4 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l3_interface_group_id(id):
+    return id + (5 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l3_mcast_group_id(vlan, id):
+    return id + (vlan << OFDPA_VLAN_ID_SHIFT)+(6 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l3_ecmp_group_id(id):
+    return id + (7 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l2_unfiltered_group_id(id):
+    return id + (11 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l2_loadbal_group_id(id):
+    return id + (12 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l2_overlay_group_id(tunnel_id, subtype, index):
+    tunnel_id=tunnel_id&0xffff #16 bits
+    subtype = subtype&3        #2 bits
+    index = index & 0x3f       #10 bits
+    return index + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+ (subtype<<OFDPA_TUNNEL_SUBTYPE_SHIFT)+(8 << OFDPA_GROUP_TYPE_SHIFT)
+
+def add_l2_unfiltered_group(ctrl, ports, send_barrier=False, allow_vlan_translation=1):
+    # group table
+    # set up untag groups for each port
+    group_id_list=[]
+    msgs=[]
+    for of_port in ports:
+        # do stuff
+        group_id = encode_l2_unfiltered_group_id(of_port)
+        group_id_list.append(group_id)
+        actions = [ofp.action.output(of_port)]
+
+        actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=allow_vlan_translation)))
+        buckets = [ofp.bucket(actions=actions)]
+        request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                        group_id=group_id,
+                                        buckets=buckets
+                                       )
+        ctrl.message_send(request)
+        msgs.append(request)
+
+        if send_barrier:
+            do_barrier(ctrl)
+
+    return group_id_list, msgs
+
+def add_one_l2_unfiltered_group(ctrl, of_port, send_barrier=False):
+    # group table
+    # set up untag groups for each port
+    group_id = encode_l2_unfiltered_group_id(of_port)
+    actions = [ofp.action.output(of_port)]
+    actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=1)))
+
+    buckets = [ofp.bucket(actions=actions)]
+    request = ofp.message.group_add(
+        group_type=ofp.OFPGT_INDIRECT,
+        group_id=group_id,
+        buckets=buckets
+    )
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return group_id, request
+
+def add_l2_interface_group(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False):
+    # group table
+    # set up untag groups for each port
+    group_id_list=[]
+    msgs=[]
+    for of_port in ports:
+        # do stuff
+        group_id = encode_l2_interface_group_id(vlan_id, of_port)
+        group_id_list.append(group_id)
+        if is_tagged:
+            actions = [
+                ofp.action.output(of_port),
+            ]
+        else:
+            actions = [
+                ofp.action.pop_vlan(),
+                ofp.action.output(of_port),
+            ]
+
+        buckets = [
+            ofp.bucket(actions=actions),
+        ]
+
+        request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                        group_id=group_id,
+                                        buckets=buckets
+                                       )
+        ctrl.message_send(request)
+        msgs.append(request)
+
+        if send_barrier:
+            do_barrier(ctrl)
+
+    return group_id_list, msgs
+
+def add_one_l2_interface_group(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False):
+    # group table
+    # set up untag groups for each port
+    group_id = encode_l2_interface_group_id(vlan_id, port)
+
+    if is_tagged:
+        actions = [
+            ofp.action.output(port),
+        ]
+    else:
+        actions = [
+            ofp.action.pop_vlan(),
+            ofp.action.output(port),
+        ]
+
+    buckets = [
+        ofp.bucket(actions=actions),
+    ]
+
+    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return group_id, request
+
+def add_l2_mcast_group(ctrl, ports, vlanid, mcast_grp_index):
+    buckets=[]
+    for of_port in ports:
+        group_id = encode_l2_interface_group_id(vlanid, of_port)
+        action=[ofp.action.group(group_id)]
+        buckets.append(ofp.bucket(actions=action))
+
+    group_id =encode_l2_mcast_group_id(vlanid, mcast_grp_index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_l2_flood_group(ctrl, ports, vlanid, id):
+    buckets=[]
+    for of_port in ports:
+        group_id = encode_l2_interface_group_id(vlanid, of_port)
+        action=[ofp.action.group(group_id)]
+        buckets.append(ofp.bucket(actions=action))
+
+    group_id =encode_l2_flood_group_id(vlanid, id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_l2_flood_group_with_gids(ctrl, gids, vlanid, id, send_barrier=False):
+    buckets=[]
+    for gid in gids:
+        action=[ofp.action.group(gid)]
+        buckets.append(ofp.bucket(actions=action))
+
+    group_id =encode_l2_flood_group_id(vlanid, id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def mod_l2_flood_group(ctrl, ports, vlanid, id):
+    buckets=[]
+    for of_port in ports:
+        group_id = encode_l2_interface_group_id(vlanid, of_port)
+        action=[ofp.action.group(group_id)]
+        buckets.append(ofp.bucket(actions=action))
+
+    group_id =encode_l2_flood_group_id(vlanid, id)
+    request = ofp.message.group_modify(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+
+def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac):
+    group_id = encode_l2_interface_group_id(vlanid, port)
+
+    action=[]
+    if src_mac is not None:
+        action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
+
+    if dst_mac is not None:
+        action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
+
+    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
+
+    action.append(ofp.action.group(group_id))
+
+    buckets = [ofp.bucket(actions=action)]
+
+    group_id =encode_l2_rewrite_group_id(id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac, send_barrier=False, gid=None):
+
+    if (not gid):
+        group_id = encode_l2_interface_group_id(vlanid, port)
+    else:
+        group_id = gid
+
+    action=[]
+    if src_mac is not None:
+        action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
+
+    if dst_mac is not None:
+        action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
+
+    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
+
+    action.append(ofp.action.group(group_id))
+
+    buckets = [ofp.bucket(actions=action)]
+
+    group_id =encode_l3_unicast_group_id(id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
+    group_id = encode_l2_interface_group_id(vlanid, port)
+
+    action=[]
+    action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
+    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
+    action.append(ofp.action.group(group_id))
+
+    buckets = [ofp.bucket(actions=action)]
+
+    group_id =encode_l3_interface_group_id(id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+
+def add_l2_loadbal_group(ctrl, id, l2_unfil_intf_groups, send_barrier=False):
+    buckets=[]
+    for group in l2_unfil_intf_groups:
+        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
+
+    group_id=encode_l2_loadbal_group_id(id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
+                                   group_id=group_id,
+                                   buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return group_id, request
+
+def mod_l2_loadbal_group(ctrl, id, l2_unfil_intf_groups, send_barrier=False):
+    buckets=[]
+    for group in l2_unfil_intf_groups:
+        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
+
+    group_id =encode_l2_loadbal_group_id(id)
+    request = ofp.message.group_modify(group_type=ofp.OFPGT_SELECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+
+def add_l3_ecmp_group(ctrl, id, l3_ucast_groups, send_barrier=False):
+    buckets=[]
+    for group in l3_ucast_groups:
+        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
+
+    group_id =encode_l3_ecmp_group_id(id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def mod_l3_ecmp_group(ctrl, id, l3_ucast_groups):
+    buckets=[]
+    for group in l3_ucast_groups:
+        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
+
+    group_id =encode_l3_ecmp_group_id(id)
+    request = ofp.message.group_modify(group_type=ofp.OFPGT_SELECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                    )
+    ctrl.message_send(request)
+    return request
+
+def add_l3_mcast_group(ctrl, vid,  mcast_group_id, groups_on_buckets):
+    buckets=[]
+    for group in groups_on_buckets:
+        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
+
+    group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_l2_overlay_flood_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
+    buckets=[]
+    for port in ports:
+        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
+
+    group_id=encode_l2_overlay_group_id(tunnel_id, 0, index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_l2_overlay_flood_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
+    buckets=[]
+    for port in ports:
+        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
+
+    group_id=encode_l2_overlay_group_id(tunnel_id, 1, index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_l2_overlay_mcast_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
+    buckets=[]
+    for port in ports:
+        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
+
+    group_id=encode_l2_overlay_group_id(tunnel_id, 2, index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_l2_overlay_mcast_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
+    buckets=[]
+    for port in ports:
+        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
+
+    group_id=encode_l2_overlay_group_id(tunnel_id, 3, index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_port_table_flow(ctrl, is_overlay=True):
+    match = ofp.match()
+
+    if is_overlay == True:
+       match.oxm_list.append(ofp.oxm.in_port(0x10000))
+       NEXT_TABLE=50
+    else:
+       match.oxm_list.append(ofp.oxm.in_port(0))
+       NEXT_TABLE=10
+
+    request = ofp.message.flow_add(
+        table_id=0,
+        cookie=42,
+        match=match,
+        instructions=[
+          ofp.instruction.goto_table(NEXT_TABLE)
+        ],
+        priority=0)
+    logging.info("Add port table, match port %lx" % 0x10000)
+    ctrl.message_send(request)
+
+def pop_vlan_flow(ctrl, ports, vlan_id=1):
+    # table 10: vlan
+    # goto to table 20
+    msgs=[]
+    for of_port in ports:
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
+            request = ofp.message.flow_add(
+                table_id=10,
+                cookie=42,
+                match=match,
+                instructions=[
+                  ofp.instruction.apply_actions(
+                    actions=[
+                      ofp.action.pop_vlan()
+                    ]
+                  ),
+                  ofp.instruction.goto_table(20)
+                ],
+                priority=0)
+            logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
+            ctrl.message_send(request)
+
+
+    return msgs
+
+def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
+    # table 10: vlan
+    # goto to table 20
+    msgs=[]
+    for of_port in ports:
+        if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
+            request = ofp.message.flow_add(
+                table_id=10,
+                cookie=42,
+                match=match,
+                instructions=[
+                  ofp.instruction.apply_actions(
+                    actions=[
+                      ofp.action.pop_vlan()
+                    ]
+                  ),
+                  ofp.instruction.goto_table(20)
+                ],
+                priority=0)
+            logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
+            ctrl.message_send(request)
+
+        if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
+            request = ofp.message.flow_add(
+                table_id=10,
+                cookie=42,
+                match=match,
+                instructions=[
+                  ofp.instruction.apply_actions(
+                    actions=[
+                      ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
+                    ]
+                  ),
+                  ofp.instruction.goto_table(20)
+                ],
+                priority=0)
+            logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
+            ctrl.message_send(request)
+            msgs.append(request)
+
+        if (flag == 4) :
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
+            request = ofp.message.flow_add(
+                table_id=10,
+                cookie=42,
+                match=match,
+                instructions=[
+                  ofp.instruction.apply_actions(
+                    actions=[
+                      ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
+                    ]
+                  ),
+                  ofp.instruction.goto_table(20)
+                ],
+                priority=0)
+            logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
+            ctrl.message_send(request)
+            msgs.append(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return msgs
+
+def del_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
+    # table 10: vlan
+    # goto to table 20
+    msgs=[]
+    for of_port in ports:
+        if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
+            request = ofp.message.flow_delete(
+                table_id=10,
+                cookie=42,
+                match=match,
+                priority=0)
+            logging.info("Del vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
+            ctrl.message_send(request)
+
+        if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0xfff))
+            request = ofp.message.flow_delete(
+                table_id=10,
+                cookie=42,
+                match=match,
+                priority=0)
+            logging.info("Del vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
+            ctrl.message_send(request)
+            msgs.append(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return msgs
+
+def add_vlan_table_flow_pvid(ctrl, in_port, match_vid=None, pvid=1, send_barrier=False):
+    """it will tag pack as untagged packet wether it has tagg or not"""
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.in_port(in_port))
+    actions=[]
+    if match_vid == None:
+        match.oxm_list.append(ofp.oxm.vlan_vid(0))
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
+        goto_table=20
+    else:
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vid, 0x1fff))
+        actions.append(ofp.action.push_vlan(0x8100))
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
+        goto_table=20
+
+    request = ofp.message.flow_add(
+        table_id=10,
+        cookie=42,
+        match=match,
+        instructions=[
+             ofp.instruction.apply_actions(actions=actions)
+            ,ofp.instruction.goto_table(goto_table)
+        ],
+        priority=0)
+    logging.info("Add PVID %d on port %d and go to table %ld" %( pvid, in_port, goto_table))
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+def add_vlan_table_flow_allow_all_vlan(ctrl, in_port, send_barrier=False):
+    """it st flow allow all vlan tag on this port"""
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.in_port(in_port))
+    match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1000))
+    request = ofp.message.flow_add(
+        table_id=10,
+        cookie=42,
+        match=match,
+        instructions=[
+            ofp.instruction.goto_table(20)
+        ],
+        priority=0)
+    logging.info("Add allow all vlan on port %d " %(in_port))
+    ctrl.message_send(request)
+
+def add_one_vlan_table_flow_translation(ctrl, of_port, vlan_id=1, new_vlan_id=-1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
+    # Install a flow for VLAN translation
+    # in VLAN table.
+    # table 10: vlan
+    # goto to table 20
+    if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
+
+        actions=[]
+        if vrf!=0:
+            actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
+        if new_vlan_id != -1:
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(20)
+            ],
+            priority=0)
+        logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
+        ctrl.message_send(request)
+
+
+def add_one_egress_vlan_table_flow(ctrl, of_port, match_vlan, inner_vlan, outer_vlan):
+
+    # used for translating single to double tagged packets only
+
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.exp4ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ACTSET_OUTPUT, of_port))
+    match.oxm_list.append(ofp.oxm.exp1ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ALLOW_VLAN_TRANSLATION, 1))
+    match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vlan,0x1fff))
+
+    actions=[]
+    actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+inner_vlan)))
+    actions.append(ofp.action.push_vlan(0x8100))
+    actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan)))
+
+    request = ofp.message.flow_add(
+            table_id=EGRESS_VLAN_FLOW_TABLE,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(EGRESS_DSCP_TABLE)
+            ],
+            priority=0)
+
+    ctrl.message_send(request)
+
+    return
+
+def add_one_vlan_table_flow(ctrl, of_port, out_vlan_id=1, vlan_id=1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
+
+    # goto to table 20
+    if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
+
+        actions=[]
+        if config["switch_type"] != 'xpliant' and vrf != 0:
+            actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
+
+        #actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(value=vlan_id)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(20)
+            ],
+            priority=0)
+        logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
+        ctrl.message_send(request)
+
+    if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
+
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
+
+        actions=[]
+        if vrf!=0:
+            actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
+
+        # actions.append(ofp.action.push_vlan(0x8100))
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+              ofp.instruction.apply_actions(
+                actions=actions
+              ),
+              ofp.instruction.goto_table(20)
+            ],
+            priority=0)
+        logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
+        ctrl.message_send(request)
+
+    if (flag == 4) :
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000,0x1fff))
+
+        actions=[]
+        if vrf!=0:
+            actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
+
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(20)
+            ],
+            priority=0)
+        logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
+        ctrl.message_send(request)
+
+    if (flag == VLAN_TABLE_FLAG_ONLY_STACKED):
+        # This flag is meant to managed stacked vlan packtes
+        # Matches on outer VLAN_ID, set OVID with outer VLAN.
+        # Finally expose inner VLAN_ID with a pop action and
+        # goto VLAN_1_FLOW_TABLE
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
+
+        actions=[]
+        # actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_OVID, value=0x1000+vlan_id)))
+        actions.append(ofp.action.pop_vlan())
+        actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_OVID, value=0x1000+vlan_id)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(VLAN_1_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan %d tagged packets on port %d and go to table %d" %( vlan_id, of_port, VLAN_1_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if (flag == VLAN_TABLE_FLAG_PRIORITY) :
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
+            request = ofp.message.flow_add(
+                table_id=10,
+                cookie=42,
+                match=match,
+                instructions=[
+                  ofp.instruction.apply_actions(
+                    actions=[
+                        ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)),
+                        ofp.action.push_vlan(0x8100),
+                        ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+out_vlan_id)),
+                    ]
+                  ),
+                  ofp.instruction.goto_table(20)
+                ],
+                priority=0)
+            logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
+            ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_one_vlan_table_flow_pw(ctrl, of_port, tunnel_index, new_vlan_id=1, vlan_id=1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False):
+    # table 10: vlan
+    # goto to table 13
+    if flag == VLAN_TABLE_FLAG_ONLY_TAG:
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id, 0x1fff))
+
+        actions=[]
+        if vlan_id == -1:
+            actions.append(ofp.action.pop_vlan())
+        if new_vlan_id > 1:
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
+        actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
+        actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
+        # 0x0000nnnn is for UNI interfaces
+        actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+              ofp.instruction.apply_actions(
+                actions=actions
+              ),
+              ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan %d tagged packets on port %d and go to table %d" % (vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid(0))
+
+        actions=[]
+        if vlan_id > 1:
+    #        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
+    #        actions.append(ofp.action.set_field(ofp.action.push_vlan(0x8100)))
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
+
+        actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
+        actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
+        # 0x0000nnnn is for UNI interfaces
+        actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+              ofp.instruction.apply_actions(
+                actions=actions
+              ),
+              ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan %d untagged packets on port %d and go to table %d" % (vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_one_vlan_1_table_flow(ctrl, of_port, new_outer_vlan_id=-1, outer_vlan_id=1, inner_vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False):
+
+    # table 11: vlan 1 table
+    # goto to table 20
+    if flag == VLAN_TABLE_FLAG_ONLY_TAG:
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
+
+        actions=[]
+        actions.append(ofp.action.push_vlan(0x8100))
+        if new_outer_vlan_id != -1:
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
+        else:
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
+
+        request = ofp.message.flow_add(
+            table_id=11,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan 1 double tagged %d-%d packets on port %d and go to table %d" %( outer_vlan_id, inner_vlan_id, of_port, TERMINATION_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
+
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
+
+        actions=[]
+        request = ofp.message.flow_add(
+            table_id=11,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan 1 double tagged %d-%d packets on port %d and go to table %d" %( outer_vlan_id, inner_vlan_id, of_port, TERMINATION_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if flag == VLAN_TABLE_FLAG_ONLY_POP_VLAN:
+
+        print("INSTALLIN IN TABLE 11!")
+
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
+
+        actions=[]
+        actions.append(ofp.action.pop_vlan())
+
+        request = ofp.message.flow_add(
+            table_id=11,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan 1 double tagged %d-%d packets on port %d and go to table %d" %( outer_vlan_id, inner_vlan_id, of_port, TERMINATION_FLOW_TABLE))
+        ctrl.message_send(request)
+
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_one_vlan_1_table_flow_pw(ctrl, of_port, tunnel_index, new_outer_vlan_id=-1, outer_vlan_id=1, inner_vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_TAG, cross_connect=False, send_barrier=False):
+
+    # table 11: vlan 1 table
+    # goto to table 13
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.in_port(of_port))
+    match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
+    match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
+
+    actions=[]
+
+    if cross_connect:
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+inner_vlan_id)))
+    actions.append(ofp.action.push_vlan(0x8100))
+    if new_outer_vlan_id != -1:
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
+    else:
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
+
+    if not cross_connect:
+        actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
+        actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
+    else:
+        actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE_CROSS_CONNECT)))
+
+    # 0x0000nnnn is for UNI interfaces
+    actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
+
+    request = ofp.message.flow_add(
+        table_id=11,
+        cookie=42,
+        match=match,
+        instructions=[
+            ofp.instruction.apply_actions(
+                 actions=actions
+            ),
+            ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
+        ],
+        priority=0)
+    logging.info("Add vlan 1 double tagged %d-%d packets on port %d and go to table %d" %( outer_vlan_id, inner_vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
+    ctrl.message_send(request)
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
+    match = ofp.match()
+    priority=500
+    if dst_mac!=None:
+        priority=1000
+        match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
+
+    match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
+
+    request = ofp.message.flow_add(
+            table_id=50,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.write_actions(
+                    actions=[
+                        ofp.action.group(group_id)]),
+                    ofp.instruction.goto_table(60)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=priority)
+
+    logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_overlay_bridge_flow(ctrl, dst_mac, vnid, group_id, is_group=True, send_barrier=False):
+    match = ofp.match()
+    if dst_mac!=None:
+        match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
+
+    match.oxm_list.append(ofp.oxm.tunnel_id(vnid))
+    if is_group == True:
+        actions=[ofp.action.group(group_id)]
+    else:
+        actions=[ofp.action.output(group_id)]
+
+    request = ofp.message.flow_add(
+            table_id=50,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.write_actions(
+                    actions=actions),
+                    ofp.instruction.goto_table(60)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1000)
+
+    logging.info("Inserting Brdige flow vnid %d, mac %s", vnid, dst_mac)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, goto_table=None, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    if dst_mac[0]&0x01 == 0x01:
+       match.oxm_list.append(ofp.oxm.eth_dst_masked(dst_mac, [0xff, 0xff, 0xff, 0x80, 0x00, 0x00]))
+       goto_table=40
+    else:
+       if in_port!=0:
+           match.oxm_list.append(ofp.oxm.in_port(in_port))
+       match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
+       match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
+       if goto_table == None:
+           goto_table=30
+
+    request = ofp.message.flow_add(
+            table_id=20,
+            cookie=42,
+            match=match,
+            instructions=[
+                    ofp.instruction.goto_table(goto_table)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+
+    logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
+    ctrl.message_send(request)
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_unicast_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_ctrl=False, send_barrier=False, priority = 1):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    if config["switch_type"] != 'xpliant' and vrf != 0:
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
+
+    match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
+
+    instructions = []
+    instructions.append(ofp.instruction.goto_table(60))
+    if send_ctrl:
+        instructions.append(ofp.instruction.write_actions(
+                            actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
+                            max_len=ofp.OFPCML_NO_BUFFER)]))
+    else:
+        instructions.append(ofp.instruction.write_actions(
+                        actions=[ofp.action.group(action_group_id)]))
+
+    request = ofp.message.flow_add(
+            table_id=30,
+            cookie=42,
+            match=match,
+            instructions=instructions,
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=priority)
+
+    logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_unicast_blackhole_flow(ctrl, eth_type, dst_ip, mask, vrf=0, send_ctrl=False, send_barrier=False, priority = 1):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    if config["switch_type"] != 'xpliant' and vrf != 0:
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
+
+    match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
+
+    instructions = []
+    instructions.append(ofp.instruction.goto_table(60))
+    instructions.append(ofp.instruction.clear_actions( ))
+
+    request = ofp.message.flow_add(
+            table_id=30,
+            cookie=42,
+            match=match,
+            instructions=instructions,
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=priority)
+
+    logging.info("Inserting unicast blackhole routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_unicast_v6_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_ctrl=False, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    if vrf != 0:
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
+
+    match.oxm_list.append(ofp.oxm.ipv6_dst_masked(parse_ipv6(dst_ip), parse_ipv6(mask)))
+
+    instructions = []
+    instructions.append(ofp.instruction.goto_table(60))
+    if send_ctrl:
+        instructions.append(ofp.instruction.write_actions(
+                            actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
+                            max_len=ofp.OFPCML_NO_BUFFER)]))
+    else:
+        instructions.append(ofp.instruction.write_actions(
+                        actions=[ofp.action.group(action_group_id)]))
+
+    request = ofp.message.flow_add(
+            table_id=30,
+            cookie=42,
+            match=match,
+            instructions=instructions,
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+
+    logging.info("Inserting unicast routing flow eth_type %lx, dip %s",eth_type, dst_ip)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_mpls_flow(ctrl, action_group_id=0x0, label=100 ,ethertype=0x0800, bos=1, vrf=1, goto_table=27, dec_ttl=False, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(0x8847))
+    match.oxm_list.append(ofp.oxm.mpls_label(label))
+    match.oxm_list.append(ofp.oxm.mpls_bos(bos))
+    write_actions = []
+    write_actions.append(ofp.action.group(action_group_id))
+    apply_actions = []
+    apply_actions = [ofp.action.dec_mpls_ttl(),
+               ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf))]
+    if (goto_table != 29):
+            apply_actions.append(ofp.action.set_field(
+                            ofp.oxm.exp2ByteValue(exp_type=23, value=32)))
+            apply_actions.append(ofp.action.copy_ttl_in())
+
+    request = ofp.message.flow_add(
+            table_id=24,
+            cookie=43,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto_table)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def xpliant_add_mpls_flow(ctrl, action_group_id=0x0, label=100 ,ethertype=0x0800, bos=1, vrf=1, goto_table=27, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(0x8847))
+    match.oxm_list.append(ofp.oxm.mpls_label(label))
+
+    apply_actions = []
+    apply_actions.append(ofp.action.group(action_group_id))
+    apply_actions.append(ofp.action.dec_mpls_ttl())
+    if (goto_table != 29):
+        apply_actions.append(ofp.action.pop_mpls(ethertype))
+
+    request = ofp.message.flow_add(
+            table_id=24,
+            cookie=43,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+    logging.info("Inserting MPLS flow , label %ld", label)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_mpls_flow_swap(ctrl, action_group_id, label, ethertype, bos, goto_table=MPLS_TYPE_FLOW_TABLE, of_port=0, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(0x8847))
+    match.oxm_list.append(ofp.oxm.mpls_label(label))
+    match.oxm_list.append(ofp.oxm.mpls_bos(1))
+
+    apply_actions = []
+    write_actions = []
+    apply_actions.append(ofp.action.dec_mpls_ttl())
+    write_actions.append(ofp.action.group(action_group_id))
+
+    request = ofp.message.flow_add(
+            table_id=24,
+            cookie=43,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto_table)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+
+    logging.info("Inserting MPLS flow , label %ld", label)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+
+def add_mpls_flow_pw(ctrl, action_group_id, label, ethertype, bos, tunnel_index, goto_table=MPLS_TYPE_FLOW_TABLE, popMPLS=True, popL2=False, of_port=0, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(0x8847))
+    match.oxm_list.append(ofp.oxm.mpls_label(label))
+    match.oxm_list.append(ofp.oxm.mpls_bos(bos))
+
+    apply_actions = []
+    write_actions = []
+    apply_actions.append(ofp.action.dec_mpls_ttl())
+    if popMPLS == True:
+        apply_actions.append(ofp.action.copy_ttl_in())
+        apply_actions.append(ofp.action.pop_mpls(ethertype))
+    if bos==1 and popL2 == True:
+        apply_actions.append(ofp.action.ofdpa_pop_l2_header())
+        apply_actions.append(ofp.action.ofdpa_pop_cw())
+        apply_actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
+        # 0x0002nnnn is for UNI interfaces
+        apply_actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00020000 + of_port)))
+        apply_actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
+
+    write_actions.append(ofp.action.group(action_group_id))
+
+    request = ofp.message.flow_add(
+            table_id=24,
+            cookie=43,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto_table)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+    logging.info("Inserting MPLS flow , label %ld", label)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(0x0800))
+    match.oxm_list.append(ofp.oxm.vlan_vid(0x1000 + vlan_id))
+    if src_ip_mask!=0:
+        match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
+    else:
+        match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))
+
+    match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
+
+    request = ofp.message.flow_add(
+            table_id=40,
+            cookie=42,
+            match=match,
+            instructions=[
+                    ofp.instruction.write_actions(
+                        actions=[ofp.action.group(action_group_id)]),
+                    ofp.instruction.goto_table(60)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+
+    logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_acl_rule(ctrl, eth_type=None, ip_proto=None, vlan_id=None, send_barrier=False):
+    match = ofp.match()
+    if eth_type:
+        match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    if ip_proto:
+        match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
+    if vlan_id:
+        match.oxm_list.append(ofp.oxm.vlan_vid(0x1000 + vlan_id))
+    request = ofp.message.flow_add(
+        table_id=60,
+        cookie=42,
+        match=match,
+        instructions=[
+                ofp.instruction.apply_actions(
+                    actions=[ofp.action.output(port=ofp.OFPP_CONTROLLER, max_len=ofp.OFPCML_NO_BUFFER)]
+                    ),
+                ],
+        buffer_id=ofp.OFP_NO_BUFFER,
+        priority=1
+        )
+    output = "Inserting ACL flow: "
+    if eth_type:
+        output += "eth_type {}, ".format(eth_type)
+    if ip_proto:
+        output += "ip_proto {}, ".format(ip_proto)
+    if vlan_id:
+        output += "vlan_id {}".format(vlan_id)
+    logging.info(output)
+
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+#dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x71000001 goto:60
+def add_dnat_flow(ctrl, eth_type, ip_dst, ip_proto, tcp_dst, set_ip_dst, set_tcp_dst, action_group_id):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    match.oxm_list.append(ofp.oxm.ipv4_dst(ip_dst))
+    match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
+    match.oxm_list.append(ofp.oxm.tcp_dst(tcp_dst))
+
+    request = ofp.message.flow_add(
+            table_id=28,
+            cookie=42,
+            match=match,
+            instructions=[
+                    ofp.instruction.write_actions(
+                        actions=[ofp.action.set_field(ofp.oxm.ipv4_dst(set_ip_dst)),
+                                 ofp.action.set_field(ofp.oxm.tcp_dst(set_tcp_dst)),
+                                 ofp.action.group(action_group_id)]),
+                    ofp.instruction.goto_table(60)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+    logging.info("Inserting DNAT flow eth_type %lx, dip %lx, ip_proto %ld, tcp_dst %ld, SetFeild: Dip %lx, tcp_dst %ld, action_gorup=%lx",eth_type, ip_dst, ip_proto, tcp_dst, set_ip_dst, set_tcp_dst, action_group_id)
+    ctrl.message_send(request)
+    return request
+
+#dpctl tcp:192.168.1.1:6633 flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30
+def add_snat_flow(ctrl, eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    match.oxm_list.append(ofp.oxm.ipv4_src(ip_src))
+    match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
+    match.oxm_list.append(ofp.oxm.tcp_src(tcp_src))
+
+    request = ofp.message.flow_add(
+            table_id=29,
+            cookie=42,
+            match=match,
+            instructions=[
+                    ofp.instruction.write_actions(
+                        actions=[ofp.action.set_field(ofp.oxm.ipv4_src(set_ip_src)),
+                                 ofp.action.set_field(ofp.oxm.tcp_src(set_tcp_src))]),
+                    ofp.instruction.goto_table(30)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+    logging.info("Inserting DNAT flow eth_type %lx, sip %lx, ip_proto %ld, tcp_src %ld, SetFeild: sip %lx, tcp_src %ld",eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src)
+    ctrl.message_send(request)
+    return request
+
+def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):
+    """
+    Command Example:
+    of-agent vtap 10001 ethernet 1/1 vid 1
+    of-agent vtp 10001 vni 10
+    """
+    if vlan != 0:
+        config_vtap_xml="""
+        <config>
+            <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+                <id>capable-switch-1</id>
+                <resources>
+                    <port xc:operation="OPERATION">
+                        <resource-id >LPORT</resource-id>
+                        <features>
+                            <current>
+                              <rate>10Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </current>
+                            <advertised>
+                              <rate>10Gb</rate>
+                              <rate>100Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </advertised>
+                            <supported>
+                              <rate>10Gb</rate>
+                              <rate>100Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </supported>
+                            <advertised-peer>
+                              <rate>10Gb</rate>
+                              <rate>100Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </advertised-peer>
+                        </features>
+                        <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
+                            <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
+                            <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
+                            <ofdpa10:vni>VNID</ofdpa10:vni>
+                        </ofdpa10:vtap>
+                    </port>
+              </resources>
+              <logical-switches>
+                  <switch>
+                    <id>DATAPATH_ID</id>
+                    <datapath-id>DATAPATH_ID</datapath-id>
+                    <resources>
+                      <port xc:operation="OPERATION">LPORT</port>
+                    </resources>
+                  </switch>
+              </logical-switches>
+            </capable-switch>
+          </config>
+        """
+    else:
+        config_vtap_xml="""
+        <config>
+            <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+                <id>capable-switch-1</id>
+                <resources>
+                    <port xc:operation="OPERATION">
+                        <resource-id >LPORT</resource-id>
+                        <features>
+                            <current>
+                              <rate>10Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </current>
+                            <advertised>
+                              <rate>10Gb</rate>
+                              <rate>100Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </advertised>
+                            <supported>
+                              <rate>10Gb</rate>
+                              <rate>100Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </supported>
+                            <advertised-peer>
+                              <rate>10Gb</rate>
+                              <rate>100Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </advertised-peer>
+                        </features>
+                        <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
+                            <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
+                            <ofdpa10:vni>VNID</ofdpa10:vni>
+                        </ofdpa10:vtap>
+                    </port>
+              </resources>
+              <logical-switches>
+                  <switch>
+                    <id>DATAPATH_ID</id>
+                    <datapath-id>DATAPATH_ID</datapath-id>
+                    <resources>
+                      <port xc:operation="OPERATION">LPORT</port>
+                    </resources>
+                  </switch>
+              </logical-switches>
+            </capable-switch>
+          </config>
+        """
+    str_datapath_id_f= "{:016x}".format(dp_id)
+    str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
+    config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)
+    config_vtap_xml=config_vtap_xml.replace("LPORT", str(int(lport)))
+    config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))
+    config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))
+    config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
+    config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
+    return config_vtap_xml
+
+def get_vtep_lport_config_xml(dp_id, lport, src_ip, dst_ip, next_hop_id, vnid, udp_src_port=6633, ttl=25, operation='merge'):
+    """
+    Command Example:
+    of-agent vtep 10002 source user-input-src-ip destination user-input-dst-ip udp-source-port 6633 nexthop 2 ttl 25
+    of-agent vtp 10001 vni 10
+    """
+
+    config_vtep_xml="""
+        <config>
+          <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <id>capable-switch-1</id>
+            <resources>
+             <port xc:operation="OPERATION">
+               <resource-id>LPORT</resource-id>
+                 <features>
+                   <current>
+                     <rate>10Gb</rate>
+                     <medium>fiber</medium>
+                     <pause>symmetric</pause>
+                   </current>
+                   <advertised>
+                     <rate>10Gb</rate>
+                     <rate>100Gb</rate>
+                     <medium>fiber</medium>
+                     <pause>symmetric</pause>
+                   </advertised>
+                   <supported>
+                     <rate>10Gb</rate>
+                     <rate>100Gb</rate>
+                     <medium>fiber</medium>
+                     <pause>symmetric</pause>
+                   </supported>
+                   <advertised-peer>
+                     <rate>10Gb</rate>
+                     <rate>100Gb</rate>
+                     <medium>fiber</medium>
+                     <pause>symmetric</pause>
+                   </advertised-peer>
+                </features>
+              <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
+                <ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
+                <ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
+                <ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
+                <ofdpa10:vni xc:operation="OPERATION">
+                    <ofdpa10:id>VNID</ofdpa10:id>
+                </ofdpa10:vni>
+                <ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
+                <ofdpa10:ttl>TTL</ofdpa10:ttl>
+              </ofdpa10:vtep>
+             </port>
+            </resources>
+            <logical-switches>
+                <switch>
+                  <id>DATAPATH_ID</id>
+                  <datapath-id>DATAPATH_ID</datapath-id>
+                  <resources>
+                    <port xc:operation="OPERATION">LPORT</port>
+                  </resources>
+                </switch>
+            </logical-switches>
+          </capable-switch>
+        </config>
+    """
+    str_datapath_id_f= "{:016x}".format(dp_id)
+    str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
+    config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)
+    config_vtep_xml=config_vtep_xml.replace("LPORT", str(int(lport)))
+    config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))
+    config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))
+    config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))
+    config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))
+    config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))
+    config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
+    config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))
+
+    return config_vtep_xml
+
+def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'):
+    #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
+    config_nexthop_xml="""
+      <config>
+          <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01"  xc:operation="OPERATION">
+              <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
+              <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
+              <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
+              <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
+            </ofdpa10:next-hop>
+          </of11-config:capable-switch>
+      </config>
+      """
+    config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
+    config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))
+    config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))
+    config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))
+    config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))
+    return config_nexthop_xml
+
+def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):
+    #of-agent vni 10 multicast 224.1.1.1 nexthop 20
+    if mcast_ipv4!=None:
+        config_vni_xml="""
+          <config>
+              <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+                <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
+                  <ofdpa10:id>VNID</ofdpa10:id>
+                  <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
+                  <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
+                </ofdpa10:vni>
+              </of11-config:capable-switch>
+          </config>
+          """
+        config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))
+        config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))
+    else:
+        config_vni_xml="""
+          <config>
+              <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+                <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
+                  <ofdpa10:id>VNID</ofdpa10:id>
+                </ofdpa10:vni>
+              </of11-config:capable-switch>
+          </config>
+          """
+
+    config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))
+    config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))
+    return config_vni_xml
+
+def get_featureReplay(self):
+    req = ofp.message.features_request()
+    res, raw = self.controller.transact(req)
+    self.assertIsNotNone(res, "Did not receive a response from the DUT.")
+    self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
+                 ("Unexpected packet type %d received in response to "
+                  "OFPT_FEATURES_REQUEST") % res.type)
+    return res
+
+def send_edit_config(switch_ip, xml, target='runing'):
+    NETCONF_ACCOUNT="netconfuser"
+    NETCONF_PASSWD="netconfuser"
+    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
+        try:
+            m.edit_config(target='running',
+                      config=xml,
+                      default_operation='merge',
+                      error_option='stop-on-error')
+
+        except Exception as e:
+            logging.info("Fail to set xml %s", xml)
+            return False
+
+    #return m.get_config(source='running').data_xml
+    return True
+
+def send_delete_config(switch_ip, xml, target='runing'):
+    NETCONF_ACCOUNT="netconfuser"
+    NETCONF_PASSWD="netconfuser"
+    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
+        try:
+            m.edit_config(target='running',
+                      config=xml,
+                      default_operation='delete',
+                      error_option='stop-on-error')
+
+        except Exception as e:
+            logging.info("Fail to set xml %s", xml)
+            return False
+
+    #return m.get_config(source='running').data_xml
+    return True
+
+def get_edit_config(switch_ip, target='runing'):
+    NETCONF_ACCOUNT="netconfuser"
+    NETCONF_PASSWD="netconfuser"
+    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
+        return m.get_config(source='running').data_xml
+
+
+"""
+MPLS
+"""
+
+OFDPA_MPLS_SUBTYPE_SHIFT=24
+OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL=1
+OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL=2
+OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1=3
+OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2=4
+OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL=5
+OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP=6
+OFDPA_MPLS_GROUP_SUBTYPE_ECMP=8
+OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG=10
+
+
+
+
+def encode_mpls_interface_group_id(subtype, index):
+    index=index&0x00ffffff
+    assert(subtype==0)
+    return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
+
+def encode_mpls_label_group_id(subtype, index):
+    index=index&0x00ffffff
+    assert(subtype <=5 or subtype==0)
+    #1: l2 vpn label
+    #2: l3 vpn label
+    #3: mpls tunnel label 1
+    #4: mpls tunnel lable 2
+    #5: mpls swap label
+    return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
+
+def encode_mpls_forwarding_group_id(subtype, index):
+    index=index&0x00ffffff
+    assert(subtype==6 or subtype==8 or subtype==10)
+    return index + (10 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
+
+
+def add_mpls_intf_group(ctrl, ref_gid, dst_mac, src_mac, vid, index, subtype=0, send_barrier=False, add=True):
+    action=[]
+    action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
+    action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
+    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vid)))
+    action.append(ofp.action.group(ref_gid))
+
+    buckets = [ofp.bucket(actions=action)]
+
+    mpls_group_id =encode_mpls_interface_group_id(subtype, index)
+    if add:
+        request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                        group_id=mpls_group_id,
+                                        buckets=buckets
+                                       )
+    else:
+        request = ofp.message.group_modify(group_type=ofp.OFPGT_INDIRECT,
+                                        group_id=mpls_group_id,
+                                        buckets=buckets
+                                       )
+
+
+    logging.debug("Adding MPLS interface group %02x, src_mac %s , dst_mac %s , vid %d", mpls_group_id, src_mac, dst_mac, vid)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+    return mpls_group_id, request
+
+def add_mpls_tunnel_label_group(
+    ctrl,
+    ref_gid,
+    subtype,
+    index,
+    label,
+    ):
+
+    action=[]
+    action.append(ofp.action.push_mpls(0x8847))
+    action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
+    action.append(ofp.action.group(ref_gid))
+    buckets = [ofp.bucket(actions=action)]
+
+    mpls_group_id = encode_mpls_label_group_id(subtype, index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                    group_id=mpls_group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+
+    return mpls_group_id, request
+
+def add_mpls_swap_label_group(
+    ctrl,
+    ref_gid,
+    subtype,
+    index,
+    label,
+    ):
+
+    action=[]
+    action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
+    action.append(ofp.action.group(ref_gid))
+    buckets = [ofp.bucket(actions=action)]
+
+    mpls_group_id = encode_mpls_label_group_id(subtype, index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                    group_id=mpls_group_id,
+                                    buckets=buckets
+                                   )
+    logging.debug("Adding MPLS Swap group %02x, label %d", mpls_group_id, label)
+    ctrl.message_send(request)
+
+    return mpls_group_id, request
+
+def add_mpls_label_group(ctrl, subtype, index, ref_gid,
+                         lmep_id=-1,
+                         qos_index=-1,
+                         push_l2_header=False,
+                         push_vlan=False,
+                         push_mpls_header=False,
+                         push_cw=False,
+                         set_mpls_label=None,
+                         set_bos=None,
+                         set_tc=None,
+                         set_tc_from_table=False,
+                         cpy_tc_outward=False,
+                         set_ttl=None,
+                         cpy_ttl_outward=False,
+                         oam_lm_tx_count=False,
+                         set_pri_from_table=False,
+                         send_barrier=False
+                         ):
+    """
+    @ref_gid: only can be mpls intf group or mpls tunnel label 1/2 group
+    """
+    action=[]
+
+    if push_vlan== True:
+        action.append(ofp.action.push_vlan(0x8100))
+    if push_mpls_header== True:
+        action.append(ofp.action.push_mpls(0x8847))
+    if set_mpls_label != None:
+        action.append(ofp.action.set_field(ofp.oxm.mpls_label(set_mpls_label)))
+    if set_bos != None:
+        action.append(ofp.action.set_field(ofp.oxm.mpls_bos(set_bos)))
+    if set_tc != None:
+        assert(set_tc_from_table==False)
+        action.append(ofp.action.set_field(ofp.oxm.mpls_tc(set_tc)))
+    if set_ttl != None:
+        action.append(ofp.action.set_mpls_ttl(set_ttl))
+    if cpy_ttl_outward == True:
+        action.append(ofp.action.copy_ttl_out())
+    """
+    ofdpa experimenter
+    """
+    if push_l2_header== True:
+        action.append(ofp.action.ofdpa_push_l2_header())
+    if set_tc_from_table== True:
+        assert(qos_index>=0)
+        assert(set_tc == None)
+        action.append(ofp.action.ofdpa_set_tc_from_table(qos_index))
+    if cpy_tc_outward == True:
+        action.append(ofp.action.ofdpa_copy_tc_out())
+    if oam_lm_tx_count == True:
+        assert(qos_index>=0 and lmep_id>=0)
+        action.append(ofp.action.ofdpa_oam_lm_tx_count(lmep_id, qos_index))
+    if set_pri_from_table == True:
+        assert(qos_index>=0)
+        action.append(ofp.action.ofdpa_set_qos_from_table(qos_index))
+    if push_cw == True:
+        action.append(ofp.action.ofdpa_push_cw())
+
+    action.append(ofp.action.group(ref_gid))
+    buckets = [ofp.bucket(actions=action)]
+
+    mpls_group_id = encode_mpls_label_group_id(subtype, index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                    group_id=mpls_group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return mpls_group_id, request
+
+def add_mpls_l2_port_flow(ctrl, of_port, mpls_l2_port, tunnel_index, ref_gid, qos_index=0, goto=MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE):
+    """
+    Only action is Group, which must indicate one of:
+    MPLS L2 VPN Label or Fast Failover Protection Group.
+    ref_gid contains this information
+    """
+
+    match = ofp.match()
+
+    write_actions = []
+    write_actions.append(ofp.action.group(ref_gid))
+    apply_actions = []
+
+    if goto==MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE:
+        tunnel_id = tunnel_index + ofp.oxm.TUNNEL_ID_BASE
+        match.oxm_list.append(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port))
+        match.oxm_list.append(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE))
+        assert(qos_index>=0)
+        apply_actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_QOS_INDEX, value=qos_index)))
+
+        request = ofp.message.flow_add(
+            table_id=MPLS_L2_PORT_FLOW_TABLE,
+            cookie=42,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto)
+                    ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+        logging.info("Inserting flow for Pseudowire Initiation %d mpls_l2_port, %d tunnel_id, action %x group and go to table %d", mpls_l2_port, tunnel_id, ref_gid, MPLS_L2_PORT_DSCP_TRUST_FLOW_TABLE)
+        ctrl.message_send(request)
+
+    if goto==ACL_FLOW_TABLE:
+        tunnel_id = tunnel_index + ofp.oxm.TUNNEL_ID_BASE
+        match.oxm_list.append(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port))
+        match.oxm_list.append(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE_CROSS_CONNECT))
+        request = ofp.message.flow_add(
+            table_id=MPLS_L2_PORT_FLOW_TABLE,
+            cookie=42,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto)
+                    ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+        logging.info("Inserting flow for VLAN Cross Connect %d mpls_l2_port, %d tunnel_id, action %x group and go to table %d", mpls_l2_port, tunnel_id, ref_gid, ACL_FLOW_TABLE)
+        ctrl.message_send(request)
+
+    return request
+
+def add_mpls_forwarding_group(ctrl, subtype, index, ref_gids,
+                              watch_port=None,
+                              watch_group=ofp.OFPP_ANY,
+                              push_vlan=None,
+                              pop_vlan=None,
+                              set_vid=None):
+    assert(subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP
+           or subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP
+           or subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG)
+
+    buckets=[]
+    if subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP:
+        group_type = ofp.OFPGT_FF
+        for gid in ref_gids:
+            action=[]
+            action.append(ofp.action.group(gid))
+            buckets.append(ofp.bucket(watch_port=watch_port, watch_group=watch_group,actions=action))
+
+    elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP:
+        group_type = ofp.OFPGT_SELECT
+        for gid in ref_gids:
+            action=[]
+            action.append(ofp.action.group(gid))
+            buckets.append(ofp.bucket(actions=action))
+
+    elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG:
+        group_type = ofp.OFPGT_INDIRECT
+        action=[]
+        if set_vid!=None:
+            action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+set_vid)))
+        if push_vlan!=None:
+            action.append(ofp.action.push_vlan(push_vlan))
+        if pop_vlan!=None:
+            action.append(ofp.action.pop_vlan())
+            action.append(ofp.action.group(ref_gids[0]))
+            buckets.append(ofp.bucket(actions=action))
+
+    mpls_group_id = encode_mpls_forwarding_group_id(subtype, index)
+    request = ofp.message.group_add(group_type=group_type,
+                                    group_id=mpls_group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return mpls_group_id, request
+
+def add_one_egress_vlan_tpid_table_flow(ctrl, of_port):
+    # Used for changing ethertype of outer vlan header to 0x88a8
+
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.exp4ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ACTSET_OUTPUT, of_port, ONF_EXPERIMENTER_ID))
+    match.oxm_list.append(ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT))
+
+    actions = []
+    actions.append(ofp.action.copy_field(
+        12, 0, 0, ['\x80\x00\x0c\x02', ofp.oxm.exp4ByteReg(oxm_field = 1).pack()])) # VLAN_VID, PACKET_REG(1)
+    actions.append(ofp.action.pop_vlan())
+    actions.append(ofp.action.push_vlan(0x88a8))
+    actions.append(ofp.action.copy_field(
+        12, 0, 0, [ofp.oxm.exp4ByteReg(oxm_field = 1).pack(), '\x80\x00\x0c\x02'])) # PACKET_REG(1), VLAN_VID
+
+    request = ofp.message.flow_add(
+        table_id=EGRESS_TPID_FLOW_TABLE,
+        cookie=42,
+        match=match,
+        instructions=[
+            ofp.instruction.apply_actions(
+                actions=actions
+            ),
+        ],
+        priority=0)
+
+    ctrl.message_send(request)
+
+    return
+
+"""
+display
+"""
+def print_current_table_flow_stat(ctrl, table_id=0xff):
+    stat_req=ofp.message.flow_stats_request()
+    response, pkt = ctrl.transact(stat_req)
+    if response == None:
+        print "no response"
+        return None
+    print len(response.entries)
+    for obj in response.entries:
+        print "match ", obj.match
+        print "cookie", obj.cookie
+        print "priority", obj.priority
+        print "idle_timeout", obj.idle_timeout
+        print "hard_timeout", obj.hard_timeout
+        #obj.actions
+        print "packet count: %lx"%obj.packet_count
+
diff --git a/Fabric/Utilities/accton/acl_flow.py b/Fabric/Utilities/accton/acl_flow.py
new file mode 100755
index 0000000..c055ba1
--- /dev/null
+++ b/Fabric/Utilities/accton/acl_flow.py
@@ -0,0 +1,71 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+

+class NoVlanOnlyAclOutputPort(base_tests.SimpleDataPlane):

+    """

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

+    """

+    def runTest(self):

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

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+        input_port=ports[0]

+        output_port=ports[1]

+        vlan_id = 10

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

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

+        #add ACL flow to output port

+        match = ofp.match()

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

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

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

+        request = ofp.message.flow_add(

+            table_id=60,

+            cookie=42,

+            match=match,

+            instructions=[

+                ofp.instruction.write_actions(

+                    actions=[

+                        ofp.action.group(gid)]

+                    )

+            ],

+            priority=1)

+        #install flow

+        self.controller.message_send(request)        

+

+        dmac_str = convertMACtoStr(dmac)

+        #send packet

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

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

+        #verify packet

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

+

+        

+        

+        

+        

+        

+        

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

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+"""

+This file test case is copied from NTC EPR bug

+"""

+

+class pvidClear(base_tests.SimpleDataPlane):

+    """

+    AOS5700-54X-00620

+    """

+    def runTest(self):

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

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+        port1=ports[0]

+        port2=ports[1]

+        

+        vlan_id = 10

+

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

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

+        #add ACL flow, in port1 out port2

+        match = ofp.match()

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

+        request = ofp.message.flow_add(

+            table_id=60,

+            cookie=42,

+            match=match,

+            instructions=[

+                ofp.instruction.write_actions(

+                    actions=[

+                        ofp.action.group(gid_p2)]

+                    )

+            ],

+            priority=1)

+        #install flow

+        self.controller.message_send(request)        

+        #add ACL flow, in port2 out port1

+        match = ofp.match()

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

+        request = ofp.message.flow_add(

+            table_id=60,

+            cookie=42,

+            match=match,

+            instructions=[

+                ofp.instruction.write_actions(

+                    actions=[

+                        ofp.action.group(gid_p1)]

+                    )

+            ],

+            priority=1)

+        #install flow

+        self.controller.message_send(request)    

+        

+        #send packet and verify packet

+        parsed_pkt = simple_tcp_packet()

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

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

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

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

+

+        

+        #add vlan flow table

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

+        #send packet and verify packet

+        parsed_pkt = simple_tcp_packet()

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

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

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

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

+         

+        #remove vlan table flow        

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

+        #send packet and verify packet

+        parsed_pkt = simple_tcp_packet()

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

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

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

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

+        

+        

+        

+            

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

+Flow Test

+

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

+"""

+

+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+class L2McastFlow(base_tests.SimpleDataPlane):

+    """

+    Test output function for an exact-match flow

+

+    Add some multicast flows

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

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

+    """

+    def runTest(self):

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

+

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        # table 10: vlan

+        # send to table 20

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

+

+        # group table

+        # set up untag groups for each port

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

+

+        # set up multicast group

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

+        

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

+

+        for test_mac in test_macs:

+            group_id = encode_l2_mcast_group_id(1, 1)

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

+

+        for test_mac in test_macs:

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

+

+            for in_port in ports:

+                # change dest based on port number

+                parsed_pkt = simple_tcp_packet(eth_dst=mactest)

+                pkt = str(parsed_pkt)

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

+                self.dataplane.send(in_port, pkt)

+

+                for ofport in ports:

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

+                        continue

+                    verify_packet(self, pkt, ofport)

+                verify_no_other_packets(self)

+

+class L2UnicastFlow(base_tests.SimpleDataPlane):

+    """

+    Test output function for an exact-match flow

+

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

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

+    to B results in an output to A.

+    """

+    def runTest(self):

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

+

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        # table 10: vlan

+        # send to table 20

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

+

+        # group table

+        # set up tag groups for each port

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

+

+        for port in ports:

+            add_one_vlan_table_flow(self.controller, port, 1)

+            group_id = encode_l2_interface_group_id(1, port)

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

+        do_barrier(self.controller)

+

+        for out_port in ports:

+            # change dest based on port number

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

+

+            for in_port in ports:

+                if in_port == out_port:

+                    continue

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

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

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

+                pkt = str(parsed_pkt)

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

+                self.dataplane.send(in_port, pkt)

+

+                for ofport in ports:

+                    if ofport in [out_port]:

+                        verify_packet(self, pkt, ofport)

+                    else:

+                        verify_no_packet(self, pkt, ofport)

+                        

+                verify_no_other_packets(self)

+

+class L2Flood(base_tests.SimpleDataPlane):

+    """

+    Test L2 unknown unicast flooding and broadcast flood

+    """

+    def runTest(self):

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

+

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        # table 10: vlan

+        # send to table 20

+        add_vlan_table_flow(self.controller, ports, 1)

+

+        # group table

+        # set up untag groups for each port

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

+

+        input_port = ports.pop()

+        flood_ports= ports

+    

+        #no fllod group create, veriy all drop

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

+        pkt = str(parsed_pkt)

+        self.dataplane.send(input_port, pkt)

+        verify_no_other_packets(self)

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

+        pkt = str(parsed_pkt)

+        self.dataplane.send(input_port, pkt)

+        verify_no_other_packets(self)        

+        #add flood groupo    

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

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

+        #verify flood 

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

+        pkt = str(parsed_pkt)

+        self.dataplane.send(input_port, pkt)

+        for ofport in flood_ports:

+            verify_packet(self, pkt, ofport)

+

+        verify_no_other_packets(self)

+               

+        for ofport in flood_ports:

+            self.dataplane.send(ofport, pkt)

+            #self won't rx packet

+            verify_no_packet(self, pkt, ofport)

+            #others will rx packet

+            tmp_ports=[]

+            for tmp in flood_ports:

+                if tmp != ofport:

+                    tmp_ports.append(tmp)                

+            verify_packets(self, pkt, tmp_ports)

+            

+        verify_no_other_packets(self)

+

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

+        pkt = str(parsed_pkt)

+        self.dataplane.send(input_port, pkt)

+        for ofport in flood_ports:

+            verify_packet(self, pkt, ofport)        

+        

+class PacketInMiss(base_tests.SimpleDataPlane):

+    """

+    Test packet in function for a table-miss flow

+

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

+    in message is received from the controller for each

+    

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

+    """

+

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        

+        parsed_pkt = simple_tcp_packet(pktlen=100)

+        parsed_vlan_pkt = simple_tcp_packet(pktlen=104, 

+                      vlan_vid=0x1001, dl_vlan_enable=True)

+        pkt = str(parsed_pkt)

+        vlan_pkt = str(parsed_vlan_pkt)

+        # table 10: vlan

+        # send to table 20

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

+

+        # group table

+        # set up untag groups for each port

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

+

+        # create match

+        match = ofp.match()

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

+        request = ofp.message.flow_add(

+            table_id=60,

+            cookie=42,

+            match=match,

+            instructions=[

+                ofp.instruction.apply_actions(

+                    actions=[

+                        ofp.action.output(

+                            port=ofp.OFPP_CONTROLLER,

+                            max_len=ofp.OFPCML_NO_BUFFER)]),

+            ],

+            buffer_id=ofp.OFP_NO_BUFFER,

+            priority=1)

+

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

+        self.controller.message_send(request)

+        do_barrier(self.controller)

+

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

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

+            self.dataplane.send(of_port, pkt)

+

+            #AOS current packet in will not have vlan tag

+            if config["cicada_poject"]:

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

+            else:

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

+

+            verify_no_other_packets(self)

+

+class PacketOut(base_tests.SimpleDataPlane):

+    """

+    Verify action Flood, ALL, in port

+    """

+

+    def runTest(self):

+        if config["cicada_poject"]:

+            pass

+            

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        

+        parsed_pkt = simple_tcp_packet(pktlen=100)

+        parsed_vlan_pkt = simple_tcp_packet(pktlen=104, 

+                      vlan_vid=0x1002, dl_vlan_enable=True)

+                      

+        pkt = str(parsed_pkt)

+        vlan_pkt = str(parsed_vlan_pkt)

+       

+        

+        #packet out flood, untag packet

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

+                                                            buffer_id=ofp.OFP_NO_BUFFER,

+                                                            actions=[ofp.action.output(

+                                                                     port=ofp.OFPP_FLOOD)],

+                                                            data=pkt)) 

+

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

+            verify_packet(self, pkt, of_port)

+

+        verify_no_other_packets(self)

+

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

+        #so we do as all action.

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

+                                                            buffer_id=ofp.OFP_NO_BUFFER,

+                                                            actions=[ofp.action.output(

+                                                                     port=ofp.OFPP_FLOOD)],

+                                                            data=vlan_pkt)) 

+

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

+            verify_packet(self, vlan_pkt, of_port)

+

+        verify_no_other_packets(self)

+

+        #packet out all

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

+                                                            buffer_id=ofp.OFP_NO_BUFFER,

+                                                            actions=[ofp.action.output(

+                                                                     port=ofp.OFPP_FLOOD)],

+                                                            data=pkt)) 

+

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

+            verify_packet(self, pkt, of_port)

+

+        verify_no_other_packets(self)        

+        

+        #packet out to in port

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

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

+                                                            buffer_id=ofp.OFP_NO_BUFFER,

+                                                            actions=[ofp.action.output(

+                                                                     port=in_port)],

+                                                            data=pkt)) 

+

+        verify_packet(self, pkt, in_port)

+        verify_no_other_packets(self)

+

+class L3UcastRoute(base_tests.SimpleDataPlane):

+    """

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

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

+    """

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

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

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

+            return

+        

+        vlan_id=1

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

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

+        dip=0xc0a80001

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

+            #add l2 interface group

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

+            dst_mac[5]=vlan_id

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

+            #add vlan flow table

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

+            #add termination flow

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

+            #add unicast routing flow

+            dst_ip = dip + (vlan_id<<8)           

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

+            vlan_id += 1

+        

+        do_barrier(self.controller)  

+        

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

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

+        #port 1 to port 2        

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

+        dst_mac[5]=1

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

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=port1_mac,

+                                       ip_ttl=64,

+                                       ip_src="192.168.1.1",

+                                       ip_dst='192.168.2.1')

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port1, pkt)

+        #build expect packet

+        dst_mac[5]=2

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

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port2_mac,

+                                       eth_src=switch_mac,

+                                       ip_ttl=63,

+                                       ip_src="192.168.1.1",

+                                       ip_dst='192.168.2.1')        

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port2)

+        verify_no_other_packets(self)

+

+        #port 2 to port 1

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

+        dst_mac[5]=2

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

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=port2_mac,

+                                       ip_ttl=64,

+                                       ip_src="192.168.2.1",

+                                       ip_dst='192.168.1.1')

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port2, pkt)

+        #build expect packet

+        dst_mac[5]=1

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

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port1_mac,

+                                       eth_src=switch_mac,

+                                       ip_ttl=63,

+                                       ip_src="192.168.2.1",

+                                       ip_dst='192.168.1.1')        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port1)

+        verify_no_other_packets(self)    

+

+class L3UcastRouteOnSamVLANSamPort(base_tests.SimpleDataPlane):

+    """

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

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

+    """	

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

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

+		

+        vlan_id=1

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

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

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

+        port_ip1=0xc0a80101        

+        port_ip1_str=convertIP4toStr(port_ip1)

+        port_ip2=0xc0a80201

+        port_ip2_str=convertIP4toStr(port_ip2)

+		#add l2 interface group

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

+		#add vlan flow table

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

+		#add termination flow

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

+

+        """192.168.1.1->192.168.2.1"""

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

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

+        """192.168.1.1->192.168.2.1"""

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

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

+ 

+        do_barrier(self.controller)  

+		

+        """send packet to verify"""

+        """192.168.1.1->192.168.2.1"""        

+        switch_mac_str = convertMACtoStr(intf_src_mac)

+        port_mac1_str  = convertMACtoStr(port_mac1)

+        port_mac2_str  = convertMACtoStr(port_mac2)

+        ttl=64

+		#send packet

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac1_str,

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac2_str,

+                                       eth_src=switch_mac_str,

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)

+

+        """192.168.2.1->192.168.1.1"""

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac2_str,

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac1_str,

+                                       eth_src=switch_mac_str,

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)    

+

+class L3UcastRouteOnDiffVLANSamPort(base_tests.SimpleDataPlane):

+    """

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

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

+    """	

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

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

+		

+        port_vlan_id1=1

+        port_vlan_id2=2

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

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

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

+        port_ip1=0xc0a80101

+        port_ip1_str=convertIP4toStr(port_ip1)

+        port_ip2=0xc0a80201

+        port_ip2_str=convertIP4toStr(port_ip2)

+		#add l2 interface group

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

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

+		#add vlan flow table

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

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

+		#add termination flow

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

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

+		

+        """192.168.1.1->192.168.2.1"""

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

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

+        """192.168.1.1->192.168.2.1"""

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

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

+ 

+        do_barrier(self.controller)  

+		

+        """send packet to verify"""  

+        """192.168.1.1->192.168.2.1"""        

+        switch_mac_str =convertMACtoStr(intf_src_mac)

+        port_mac1_str= convertMACtoStr(port_mac1)

+        port_mac2_str= convertMACtoStr(port_mac2)

+        ttl=64

+		#send packet

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac1_str,

+									   dl_vlan_enable=True,

+									   vlan_vid=port_vlan_id1,									   

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac2_str,

+                                       eth_src=switch_mac_str,

+									   dl_vlan_enable=True,

+									   vlan_vid=port_vlan_id2,									   

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)

+

+        """192.168.2.1->192.168.1.1"""

+        switch_mac = convertMACtoStr(intf_src_mac)

+        port_mac2_str=convertMACtoStr(port_mac2)

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac2_str,

+									   dl_vlan_enable=True,

+									   vlan_vid=port_vlan_id2,									   

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac1_str,

+                                       eth_src=switch_mac_str,

+									   dl_vlan_enable=True,

+									   vlan_vid=port_vlan_id1,

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)    

+		

+class L3UcastVrfRouteOnSamVLANSamPort(base_tests.SimpleDataPlane):

+    """

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

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

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

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

+    

+    """	

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

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

+		

+        vrf1=1

+        vrf2=2

+        vrf1_vlan_id=1

+        vrf2_vlan_id=2

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

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

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

+        port_ip1=0xc0a80101        

+        port_ip1_str=convertIP4toStr(port_ip1)

+        port_ip2=0xc0a80201

+        port_ip2_str=convertIP4toStr(port_ip2)

+		#add l2 interface group

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

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

+		#add vlan flow table

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

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

+        

+		#add termination flow

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

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

+        

+        """192.168.1.1->192.168.2.1"""

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

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

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

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

+        

+        """192.168.1.1->192.168.2.1"""

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

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

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

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

+        

+        do_barrier(self.controller)  

+	

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

+        """192.168.1.1->192.168.2.1"""        

+        switch_mac_str = convertMACtoStr(intf_src_mac)

+        port_mac1_str  = convertMACtoStr(port_mac1)

+        port_mac2_str  = convertMACtoStr(port_mac2)

+        ttl=64

+		#send packet

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac1_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf1_vlan_id,

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac2_str,

+                                       eth_src=switch_mac_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf1_vlan_id,                                       

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)

+

+        """192.168.2.1->192.168.1.1"""

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac2_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf1_vlan_id,                                       

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac1_str,

+                                       eth_src=switch_mac_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf1_vlan_id,                                       

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)    

+       

+		

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

+        """192.168.1.1->192.168.2.1"""        

+        switch_mac_str = convertMACtoStr(intf_src_mac)

+        port_mac1_str  = convertMACtoStr(port_mac1)

+        port_mac2_str  = convertMACtoStr(port_mac2)

+        ttl=64

+		#send packet

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac1_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf2_vlan_id,

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac2_str,

+                                       eth_src=switch_mac_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf2_vlan_id,                                       

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)

+

+        """192.168.2.1->192.168.1.1"""

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac2_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf2_vlan_id,                                       

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac1_str,

+                                       eth_src=switch_mac_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf2_vlan_id,                                       

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)          

+        

+        

+		  

+                

+class L3UcastECMP(base_tests.SimpleDataPlane):

+    """

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

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

+    """

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

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

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

+            return

+        

+        vlan_id=1

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

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

+        dip=0xc0a80001

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

+            #add l2 interface group

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

+            dst_mac[5]=vlan_id

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

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

+            #add vlan flow table

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

+            #add termination flow

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

+            #add unicast routing flow

+            dst_ip = dip + (vlan_id<<8)

+            #ECMP shall have prefix not 32

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

+            vlan_id += 1

+        

+        do_barrier(self.controller)  

+        

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

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

+        #port 1 to port 2        

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

+        dst_mac[5]=1

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

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=port1_mac,

+                                       ip_ttl=64,

+                                       ip_src="192.168.1.1",

+                                       ip_dst='192.168.2.1')

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port1, pkt)

+        #build expect packet

+        dst_mac[5]=2

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

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port2_mac,

+                                       eth_src=switch_mac,

+                                       ip_ttl=63,

+                                       ip_src="192.168.1.1",

+                                       ip_dst='192.168.2.1')        

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port2)

+        verify_no_other_packets(self)

+

+        #port 2 to port 1

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

+        dst_mac[5]=2

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

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=port2_mac,

+                                       ip_ttl=64,

+                                       ip_src="192.168.2.1",

+                                       ip_dst='192.168.1.1')

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port2, pkt)

+        #build expect packet

+        dst_mac[5]=1

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

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port1_mac,

+                                       eth_src=switch_mac,

+                                       ip_ttl=63,

+                                       ip_src="192.168.2.1",

+                                       ip_dst='192.168.1.1')        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port1)

+        verify_no_other_packets(self)    

+

+                

+class L3UcastECMP2(base_tests.SimpleDataPlane):

+    """

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

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

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

+    """

+    

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

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

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

+            return

+        

+        vlan_id=1

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

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

+

+        l3_ucast_gips=[]        

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

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

+            #add l2 interface group

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

+            if tx_port != port:            

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

+                l3_ucast_gips.append(l3_msg.group_id)

+            #add vlan flow table

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

+            #add termination flow

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

+            vlan_id += 1

+

+        tx_dip=0x0a0a0a0a

+        tx_sip=0x0b0a0a0a             

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

+        #ECMP shall have prefix not 32

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

+

+        do_barrier(self.controller)          

+

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

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

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

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=packet_src_mac,

+                                       ip_ttl=64,

+                                       ip_src=convertIP4toStr(tx_sip),

+                                       ip_dst=convertIP4toStr(tx_dip))

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

+        #build expect packet

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

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                   eth_dst=dst_mac,

+                                   eth_src=switch_mac,

+                                   ip_ttl=63,

+                                   ip_src=convertIP4toStr(tx_sip),

+                                   ip_dst=convertIP4toStr(tx_dip)) 

+                                       

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

+        verify_no_other_packets(self)

+        tx_sip=tx_sip+0x01000000  

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

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=packet_src_mac,

+                                       ip_ttl=64,

+                                       ip_src=convertIP4toStr(tx_sip),

+                                       ip_dst=convertIP4toStr(tx_dip))

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

+        #build expect packet

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

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                   eth_dst=dst_mac,

+                                   eth_src=switch_mac,

+                                   ip_ttl=63,

+                                   ip_src=convertIP4toStr(tx_sip),

+                                   ip_dst=convertIP4toStr(tx_dip)) 

+                                       

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

+        verify_no_other_packets(self)

+

+class L3McastRoute1(base_tests.SimpleDataPlane):

+    """

+    Mcast routing, From VLAN 1 to VLAN 2

+    """

+    def runTest(self):          

+        """

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

+        """

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

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

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

+            return

+

+        vlan_id =1

+        port2_out_vlan=2

+        port3_out_vlan=3

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

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

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

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

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

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

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

+        src_ip=0xc0a80101

+        src_ip_str="192.168.1.1"

+        dst_ip=0xe0010101

+        dst_ip_str="224.1.1.1"

+        

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

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

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

+

+        #add l2 interface group

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

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

+            #add vlan flow table

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

+            vlan_id +=1            

+

+        #add termination flow

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

+

+        #add l3 interface group

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

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

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

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

+        

+        parsed_pkt = simple_udp_packet(pktlen=100, 

+                                       eth_dst=dst_mac_str,

+                                       eth_src=port1_mac_str,

+                                       ip_ttl=64,

+                                       ip_src=src_ip_str,

+                                       ip_dst=dst_ip_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port1, pkt)            

+        parsed_pkt = simple_udp_packet(pktlen=100, 

+                                       eth_dst=dst_mac_str,

+                                       eth_src=intf_src_mac_str,

+                                       ip_ttl=63,

+                                       ip_src=src_ip_str,

+                                       ip_dst=dst_ip_str)

+        pkt=str(parsed_pkt)            

+        verify_packet(self, pkt, port2)

+        verify_packet(self, pkt, port3)        

+        verify_no_other_packets(self)               

+

+class L3McastRoute2(base_tests.SimpleDataPlane):

+    """

+    Mcast routing, but on same vlan (l2mcast)

+    """

+    def runTest(self):          

+        """

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

+        """

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        

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

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

+            return

+

+        vlan_id =1

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

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

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

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

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

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

+        src_ip=0xc0a80101

+        src_ip_str="192.168.1.1"

+        dst_ip=0xe0010101

+        dst_ip_str="224.1.1.1"

+        

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

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

+

+        

+        #add l2 interface group

+        l2_intf_group_list=[]

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

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

+                continue

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

+            l2_intf_group_list.append(l2_intf_gid)

+            #add vlan flow table

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

+

+        #add termination flow

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

+

+        #add l3 interface group

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

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

+

+        parsed_pkt = simple_udp_packet(pktlen=100, 

+                                       eth_dst=dst_mac_str,

+                                       eth_src=port1_mac_str,

+                                       ip_ttl=64,

+                                       ip_src=src_ip_str,

+                                       ip_dst=dst_ip_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port1, pkt)            

+        verify_packet(self, pkt, port2)

+        verify_no_other_packets(self)               

+            

+

+            

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

+Flow Test

+

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

+"""

+

+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+class qinq(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)   

+        

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

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

+        out_vlan=10

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

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

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

+        #add acl 

+        match = ofp.match()

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

+        request = ofp.message.flow_add(

+                table_id=60,

+                cookie=42,

+                match=match,

+                instructions=[

+                    ofp.instruction.write_actions(

+                        actions=[

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

+                    ],

+                buffer_id=ofp.OFP_NO_BUFFER,

+                priority=1000) 

+        self.controller.message_send(request)  

+     

+        #input untag packet

+

+        parsed_pkt = simple_tcp_packet(pktlen=100)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(in_port, pkt)

+    

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

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

+

+        #input tag packet

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

+        pkt = str(parsed_pkt)

+        self.dataplane.send(in_port, pkt)

+    

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

+                                                in_dl_vlan_enable=True, in_vlan_vid=1)

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

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

+Group table test

+Verify each group table can created correctly

+"""

+from oftest import config

+

+import logging

+import random

+

+from oftest import config

+import oftest

+import oftest.base_tests as base_tests

+import ofp

+

+from oftest.testutils import *

+from accton_util import *

+

+def getkey(type):

+    def byGroupId(stats_entry):

+        return stats_entry.group_id

+        

+    def byGroupType(stats_entry):

+        return stats_entry.group_type

+

+        

+    if type == "group_id":

+        return byGroupId

+    elif type == "group_type":

+        return byGroupType

+    else:

+         assert(0)

+    return byGroupId        

+               

+class L2InterfaceGroupOne(base_tests.SimpleDataPlane):

+    def runTest(self):    

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+

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

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

+ 

+        verify_group_stats=[ofp.group_desc_stats_entry(

+                          group_type=msg1.group_type,

+                          group_id=msg1.group_id,

+                          buckets=msg1.buckets)]

+

+        self.maxDiff=None

+

+        self.assertEquals(stats, verify_group_stats)

+

+class L2InterfaceGroup(base_tests.SimpleDataPlane):

+    def runTest(self):    

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+

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

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

+        

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

+ 

+        verify_group_stats=[]

+

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets))        

+

+        for msg in msg2:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets))

+

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

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

+        #self.maxDiff=None        

+        self.assertEquals(stats, verify_group_stats)

+        

+class L2McastGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

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

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

+        

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

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

+

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

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+                                  

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

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

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)

+

+

+class L2FloodGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

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

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

+        

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

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

+

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

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+                                  

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

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

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)

+

+

+class L2RewriteGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

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

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

+        

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

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

+

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

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+

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

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

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)

+        

+

+class L3UnicastGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

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

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

+        

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

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

+

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

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+                                  

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

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

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)  

+

+

+class L3ECMPGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

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

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

+        

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

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

+

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

+        

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

+        

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

+

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg5.group_type,

+                                  group_id=msg5.group_id,

+                                  buckets=msg5.buckets)

+                                  )

+

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

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

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)     

+

+

+class L3InterfaceGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

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

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

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

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

+

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

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+

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

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

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)     

+

+

+class L3McastGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

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

+        # Vlan 3 foward to vlan 1 port 1

+        # Vlan 3 foward to vlan 2 port 1     

+        # Vlan 3 foward to vlan 2 port 2             

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

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

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

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

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

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

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

+        

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

+        group_actions.extend(group_list3)

+

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

+        

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

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+        for msg in msg5:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg6.group_type,

+                                  group_id=msg6.group_id,

+                                  buckets=msg6.buckets)

+                                  )                                      

+        for msg in msg7:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )                                      

+                                      

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg8.group_type,

+                                  group_id=msg8.group_id,

+                                  buckets=msg8.buckets)

+                                  )  

+

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

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

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)     

+        

+        

+class mpls_intf_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	2. ref l2_flood_group

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

+        

+        #ref l2_intf_group

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

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

+            

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

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

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

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

+        self.assertEquals(stats, verify_group_stats)       

+              

+

+class mpls_l2_vpn_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

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

+        #ref l2_intf_group

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

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

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

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=False,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )

+                   

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )                                  

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

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

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

+        #DumpGroup(stats, verify_group_stats)

+        #AssertGroup(self, stats, verify_group_stats)

+        self.assertEquals(stats, verify_group_stats)       

+		

+

+class mpls_tunnel_lable1_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

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

+        #ref l2_intf_group

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

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

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

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=True,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )

+            

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

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )

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

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

+        self.assertEquals(stats, verify_group_stats)       

+		

+

+class mpls_tunnel_lable2_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

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

+        #ref l2_intf_group

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

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

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

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=True,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )

+            

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

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )                                  

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

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

+        self.assertEquals(stats, verify_group_stats)       

+		

+class mpls_swap_label_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

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

+        #ref l2_intf_group

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

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

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

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=True,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )

+            

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

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )                                    

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

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

+        self.assertEquals(stats, verify_group_stats)       

+

+

+class mpls_forwarding_group_fastfailover(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller) 

+

+        test_vid=1

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

+        #ref l2_intf_group

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

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

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

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=True,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )        

+        mpls_fwd_gid, mpls_fwd_msg=add_mpls_forwarding_group(self.controller, 

+                                                             subtype=OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP, 

+                                                             index=1, 

+                                                             ref_gids=[mpls_label_gid], 

+                                                             watch_port=test_port, 

+                                                             watch_group=ofp.OFPP_ANY, 

+                                                             push_vlan=None,

+                                                             pop_vlan=None,

+                                                             set_vid=None)

+            

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

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_fwd_msg.group_type,

+                                  group_id=mpls_fwd_msg.group_id,

+                                  buckets=mpls_fwd_msg.buckets)

+                                  )                                    

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

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

+        self.assertEquals(stats, verify_group_stats)       

+

+

+class mpls_forwarding_group_ecmp(base_tests.SimpleDataPlane):

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

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller) 

+

+        test_vid=1

+        mpls_intf_msgs=[]

+        mpls_intf_gids=[]

+        l2_intf_msgs=[]

+        index=1

+        #ref l2_intf_group

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

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

+            l2_intf_msgs.append(l2_intf_msg)            

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

+            index=index+1

+            mpls_intf_msgs.append(mpls_intf_msg)

+            mpls_intf_gids.append(mpls_intf_gid)

+            

+        mpls_fwd_gid, mpls_fwd_msg=add_mpls_forwarding_group(self.controller, 

+                                                             subtype=OFDPA_MPLS_GROUP_SUBTYPE_ECMP, 

+                                                             index=1, 

+                                                             ref_gids=mpls_intf_gids, 

+                                                             watch_port=None, 

+                                                             watch_group=None,

+                                                             push_vlan=None,

+                                                             pop_vlan=None,

+                                                             set_vid=None)

+            

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

+        

+        verify_group_stats=[]

+        for msg in l2_intf_msgs:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        for msg in mpls_intf_msgs:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_fwd_msg.group_type,

+                                  group_id=mpls_fwd_msg.group_id,

+                                  buckets=mpls_fwd_msg.buckets)

+                                  )                                    

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

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

+        self.assertEquals(stats, verify_group_stats)       

+

+

+class mpls_forwarding_group_l2tag(base_tests.SimpleDataPlane):

+    """chip not support

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller) 

+

+        test_vid=1

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

+        index=1

+        #ref l2_intf_group        

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

+

+        mpls_fwd_gid, mpls_fwd_msg=add_mpls_forwarding_group(self.controller, 

+                                                             subtype=OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG, 

+                                                             index=1, 

+                                                             ref_gids=l2_intf_gid, 

+                                                             watch_port=None, 

+                                                             watch_group=None,

+                                                             push_vlan=None,

+                                                             pop_vlan=None,

+                                                             set_vid=1)

+            

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

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_fwd_msg.group_type,

+                                  group_id=mpls_fwd_msg.group_id,

+                                  buckets=mpls_fwd_msg.buckets)

+                                  )                                    

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

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

+

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

+Nat Test

+

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

+"""

+

+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+class dnat(base_tests.SimpleDataPlane):

+    """

+    [DNAT]

+      DNAT (inbound)

+

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

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

+

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

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

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

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

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

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

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

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        

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

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

+        

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

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

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

+

+        input_pkt = simple_tcp_packet(pktlen=100, 

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

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

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 200,

+                                       ip_ttl=64,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='100.0.0.1',

+                                       tcp_dport=5000)

+        output_pkt = simple_tcp_packet(pktlen=100, 

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

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

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 100,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='10.0.0.1',

+                                       tcp_dport=2000)

+                                       

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

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

+         

+        

+        

+class dnatEcmp(base_tests.SimpleDataPlane):

+    """

+    [DNAT ECMP]

+      DNAT (inbound) with ECMP

+

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

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

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

+

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

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

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

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

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

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

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

+    

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

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

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

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+

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

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

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

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

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

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

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

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

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

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

+        

+        

+        input_pkt = simple_tcp_packet(pktlen=100, 

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

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

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 200,

+                                       ip_ttl=64,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='100.0.0.1',

+                                       tcp_dport=5000)

+        output_pkt = simple_tcp_packet(pktlen=100, 

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

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

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 100,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='10.0.0.1',

+                                       tcp_dport=2000)

+        output_pkt2 = simple_tcp_packet(pktlen=100, 

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

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

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 2,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='10.0.0.1',

+                                       tcp_dport=2000)

+

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

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

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

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

+        

+class snat_ecmp(base_tests.SimpleDataPlane):

+    """

+    [SNAT ECMP]

+      SNAT (outbound) with ECMP

+

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

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

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

+

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

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

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

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

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

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

+    

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

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

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

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

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

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+        

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

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

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

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

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

+        

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

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

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

+

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

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

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

+

+        input_pkt = simple_tcp_packet(pktlen=100, 

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

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

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 100,

+                                       ip_ttl=64,                                       

+                                       ip_src='10.0.0.1',

+                                       ip_dst="200.0.0.1",

+                                       tcp_sport=2000)

+        output_pkt = simple_tcp_packet(pktlen=100, 

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

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

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 200,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="100.0.0.1",

+                                       ip_dst='200.0.0.1',

+                                       tcp_sport=5000)

+        output_pkt2 = simple_tcp_packet(pktlen=100, 

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

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

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 5,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="100.0.0.1",

+                                       ip_dst='200.0.0.1',

+                                       tcp_sport=5000)

+

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

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

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

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

+        

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

+class l3Route(base_tests.SimpleDataPlane):

+    """

+    [L3 unicast route]

+      Do unicast route and output to specified port

+    

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

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

+    

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

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

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

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

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

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

+    """

+    def runTest(self):   

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

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

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]    

+

+        add_port_table_flow(self.controller, is_overlay=False)

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

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

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

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

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

+

+        #verify tx/rx packet

+        input_pkt = simple_tcp_packet(pktlen=100, 

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

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

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 2,

+                                       ip_ttl=64,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='192.168.2.2')

+        output_pkt = simple_tcp_packet(pktlen=100, 

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

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

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 3,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='192.168.2.2')        

+

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

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

+        

+        

+        

+        

+        

+        

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

+Flow Test

+

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

+"""

+

+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+import oftest.parse as decode

+       

+class VxlanConfigNetconf(base_tests.SimpleDataPlane):

+    """

+    Verify netconf to configure Vxlan port

+	"""

+    def runTest(self):

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

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

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        

+        #paramaters

+        access_port_vid=1

+        access_phy_port=1

+        access_lport=0x10001

+        vnid=103

+        next_hop_id=1

+        next_hop_id_mcast=2

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

+        mcast_ipv4="224.1.1.1"

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

+        network_port_phy_port=2

+        network_lport=0x10002

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+

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

+		#get datapath_id from feature message

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

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

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

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)

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

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

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, 

+                                          mcast_ipv4=mcast_ipv4, 

+                                          next_hop_id=next_hop_id_mcast)

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

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

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport, phy_port=access_phy_port, 

+                                        vlan=access_port_vid, vnid=vnid)

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

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

+

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

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

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

+            

+        get_edit_config(config["switch_ip"])

+

+		#exit verification so clear all configuration

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport, phy_port=access_phy_port, 

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

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

+        

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

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

+

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, 

+                                          mcast_ipv4=mcast_ipv4, 

+                                          next_hop_id=next_hop_id_mcast, operation="delete")

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

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

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

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

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

+

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

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

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

+        #netopeer may have problem on xml process

+        #assert(xml_before == xml_after)

+        

+class OverlayFloodGroup(base_tests.SimpleDataPlane):

+    """

+	create two lport

+	"""

+    def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

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

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

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        #paramaters

+        access_port_vid=1

+        access_phy_port=1

+        access_lport=0x10001

+        vnid=103

+        next_hop_id=1

+        next_hop_id_mcast=2

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

+        mcast_ipv4="224.1.1.1"

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

+        network_port_phy_port=2

+        network_lport=0x10002

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+		

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

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

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

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

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

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

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport, phy_port=access_phy_port, 

+                                        vlan=access_port_vid, vnid=vnid)

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

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

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)

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

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

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

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

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

+

+        #add flow over unicast group

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

+        #verify

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

+        verify_group_stats=(ofp.group_desc_stats_entry(

+    	                    group_type=msg.group_type,

+						    group_id=msg.group_id,

+						    buckets=msg.buckets))

+

+        self.assertEquals(stats, [verify_group_stats])

+        #clear all group

+        delete_all_groups(self.controller)

+		#

+		#flood over mcast

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

+

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

+ 

+        verify_group_stats=(ofp.group_desc_stats_entry(

+    	                    group_type=msg.group_type,

+						    group_id=msg.group_id,

+						    buckets=msg.buckets))

+

+        self.assertEquals(stats, [verify_group_stats])

+        #clear all group

+        delete_all_groups(self.controller)

+		#exit verification so clear all configuration

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport, phy_port=access_phy_port, 

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

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

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

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

+

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

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

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

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

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

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

+

+class OverlayMcastGroup(base_tests.SimpleDataPlane):

+    """

+	create two lport

+	"""

+    def runTest(self):

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

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

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        #paramaters

+        access_port_vid=1

+        access_phy_port=1

+        access_lport=0x10001

+        vnid=103

+        next_hop_id=1

+        next_hop_id_mcast=2

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

+        mcast_ipv4="224.1.1.1"

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

+        network_port_phy_port=2

+        network_lport=0x10002

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+		

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

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

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

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

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

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

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport, phy_port=access_phy_port, 

+                                        vlan=access_port_vid, vnid=vnid)

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

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

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)

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

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

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

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

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

+

+        #add flow over unicast group

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

+        #verify

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

+        verify_group_stats=(ofp.group_desc_stats_entry(

+    	                    group_type=msg.group_type,

+						    group_id=msg.group_id,

+						    buckets=msg.buckets))

+

+        self.assertEquals(stats, [verify_group_stats])

+        #clear all group

+        delete_all_groups(self.controller)

+		#

+		#flood over mcast

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

+

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

+ 

+        verify_group_stats=(ofp.group_desc_stats_entry(

+    	                    group_type=msg.group_type,

+						    group_id=msg.group_id,

+						    buckets=msg.buckets))

+

+        self.assertEquals(stats, [verify_group_stats])

+        #clear all group

+        delete_all_groups(self.controller)

+		#exit verification so clear all configuration

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport, phy_port=access_phy_port, 

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

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

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

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

+

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

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

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

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

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

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

+										        

+class AccessToNetworkDLFMcast(base_tests.SimpleDataPlane):

+    def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

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

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

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        access_port1_vid=1

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

+        access_lport1=0x10001

+        access_port2_vid=0

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

+        access_lport2=0x10002

+        vnid=10

+        next_hop_id=1

+        next_hop_id_mcast=2

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

+        mcast_ipv4="224.1.1.1"

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

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

+        network_lport=0x10003

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

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

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

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

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

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

+        

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

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

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

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

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

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

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

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

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

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

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

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

+

+        #get_edit_config(config["switch_ip"])

+        

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

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

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

+

+		#add DLF bridge flow

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

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

+        

+        #send packet on access port

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+

+        #verify packet on access port		

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

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

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

+        #we can easy to check VxLAN IP header

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+

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

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on network port		

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

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

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

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

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

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

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

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

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

+        

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

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

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

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

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

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

+

+class AccessToNetworkDLFUcast(base_tests.SimpleDataPlane):

+    def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

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

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

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        access_port1_vid=1

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

+        access_lport1=0x10001

+        access_port2_vid=0

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

+        access_lport2=0x10002

+        vnid=10

+        next_hop_id=1

+        next_hop_id_mcast=2

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

+        mcast_ipv4="224.1.1.1"

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

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

+        network_lport=0x10003

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

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

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

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

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

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

+        

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

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

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

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

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

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

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

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

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

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

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

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

+

+        #get_edit_config(config["switch_ip"])

+        

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

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

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

+

+		#add DLF bridge flow

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

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

+        

+        #send packet on access port

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+

+        #verify packet on access port		

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

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

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

+        #we can easy to check VxLAN IP header

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+

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

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on network port		

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

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

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

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

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

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

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

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

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

+        

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

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

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

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

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

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

+

+class AccessWithAccessDiffPortVlan(base_tests.SimpleDataPlane):

+   def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

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

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

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        access_port1_vid=1

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

+        access_lport1=0x10001

+        access_port2_vid=0

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

+        access_lport2=0x10002

+        access_port3_vid=3

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

+        access_lport3=0x10003

+        vnid=10

+        next_hop_id_mcast=1

+        mcast_ipv4="224.1.1.1"

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

+        

+        feature_reply=get_featureReplay(self)	

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=access_phy_port3, 

+												  vlan=access_port3_vid)        

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

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

+

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

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

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

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

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

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

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

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

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

+        

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport3, phy_port=access_phy_port3, 

+                                        vlan=access_port3_vid, vnid=vnid)

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

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

+

+        

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

+		#add DLF bridge flow

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

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

+        

+        #send packet on access port

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+

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

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

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

+        #verify packet on access port 3

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port3_vid)

+        pkt = str(parsed_pkt)

+        verify_packet(self, pkt, access_phy_port3) 

+        verify_no_other_packets(self)

+        

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

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

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

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)        

+        verify_no_other_packets(self)

+

+

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

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port3_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port3)

+        verify_no_other_packets(self)

+

+        

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

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

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

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

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

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

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport3, phy_port=access_phy_port3, 

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

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

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

+        

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

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

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=access_phy_port3, 

+												  vlan=access_port3_vid, operation="delete")

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

+

+        

+class AccessWithAccessSamePortDiffVlan(base_tests.SimpleDataPlane):

+   def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

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

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

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        access_port1_vid=1

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

+        access_lport1=0x10001

+        access_port2_vid=2

+        access_phy_port2= access_phy_port1

+        access_lport2=0x10002

+        access_port3_vid=3

+        access_phy_port3=access_phy_port1

+        access_lport3=0x10003

+        vnid=10

+        next_hop_id_mcast=1

+        mcast_ipv4="224.1.1.1"

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

+        

+        feature_reply=get_featureReplay(self)	

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=access_phy_port3, 

+												  vlan=access_port3_vid)        

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

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

+

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

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

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

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

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

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

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

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

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

+        

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport3, phy_port=access_phy_port3, 

+                                        vlan=access_port3_vid, vnid=vnid)

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

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

+

+        

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

+		#add DLF bridge flow

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

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

+        

+        #send packet on access port

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+

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

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

+                                       dl_vlan_enable = True,

+                                       vlan_vid = access_port2_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

+        #verify packet on access port 3

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port3_vid)

+        pkt = str(parsed_pkt)

+        verify_packet(self, pkt, access_phy_port3) 

+        verify_no_other_packets(self)

+        

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

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

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

+                                       dl_vlan_enable = True,

+                                       vlan_vid = access_port2_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)        

+        verify_no_other_packets(self)

+

+

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

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port3_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port3)

+        verify_no_other_packets(self)

+

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

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port2_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

+        verify_no_other_packets(self)        

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

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

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

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

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

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

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport3, phy_port=access_phy_port3, 

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

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

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

+        

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

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

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=access_phy_port3, 

+												  vlan=access_port3_vid, operation="delete")

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

+

+        

+class AccessWithNetwork(base_tests.SimpleDataPlane):

+    def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

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

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

+            return

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        access_port1_vid=1

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

+        access_lport1=0x10001

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

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

+        access_port2_vid=0

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

+        access_lport2=0x10002

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

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

+        vnid=10

+        next_hop_id=1

+        next_hop_id_mcast=2

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

+        mcast_ipv4="224.1.1.1"

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

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

+        network_lport=0x10003

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

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

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

+

+

+        

+        feature_reply=get_featureReplay(self)	

+        #get switch CPU mac

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

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

+        switch_cpu_mac_str=str_datapath_id[6:]

+        switch_cpu_mac = switch_cpu_mac_str.split(":")

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

+

+        #add config vtep/vtap/nexthop/vni        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

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

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

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

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

+

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

+        

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

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

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

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

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

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

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

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

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

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

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

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

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

+

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+        add_port_table_flow(self.controller, is_overlay=False)

+        

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

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

+        #add network mac

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

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

+

+        #add termination table for network port

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

+                             dst_mac=switch_cpu_mac, vlanid=network_port_vlan)

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

+        add_one_vlan_table_flow(self.controller, of_port=network_port_phy_port, 

+                                vlan_id=network_port_vlan)

+

+        #tx packet on access lport 1        

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on network port	

+        #need find a way to verify vxlan header        

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

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+        

+        #tx packet on network lport

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

+        vxlan_pkt = simple_vxlan_packet(eth_dst=switch_cpu_mac_str,

+                                        vnid=vnid, 

+                                        ip_dst= network_port_sip, 

+                                        ip_src=network_port_dip,

+                                        inner_payload=inner_pkt)

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

+        #verify

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

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        

+        verify_packet(self, inner_pkt, access_phy_port1)

+        verify_no_other_packets(self)

+

+

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

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

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

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

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

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

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

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

+        

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

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

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

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

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

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

+        

+class NetworkToNetwork(base_tests.SimpleDataPlane):

+    def runTest(self):

+        """

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

+        """

+        return

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

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

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        vnid=10

+        mcast_ipv4="224.1.1.1"

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

+        next_hop_id_mcast=3

+

+        access_port1_vid=1

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

+        access_lport1=0x10001

+

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

+        network_lport1=0x10003

+        network_port1_vlan=2

+        network_port1_sip="192.168.1.1"

+        network_port1_dip="192.168.2.1"

+        network_port1_next_hop_id=1

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

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

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

+        

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

+        network_lport2=0x10004

+        network_port2_vlan=3

+        network_port2_sip="192.168.3.1"

+        network_port2_dip="192.168.4.1"

+        network_port2_next_hop_id=2

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

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

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

+        

+        feature_reply=get_featureReplay(self)	

+        #get switch CPU mac

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

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

+        switch_cpu_mac_str=str_datapath_id[6:]

+        switch_cpu_mac = switch_cpu_mac_str.split(":")

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

+        #config vlxan

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=network_port1_next_hop_id, 

+		                                          dst_mac=network_port1_dst_mac, 

+												  phy_port=network_port1_phy_port, 

+												  vlan=network_port1_vlan)        

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

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

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=network_port2_next_hop_id, 

+		                                          dst_mac=network_port2_dst_mac, 

+												  phy_port=network_port2_phy_port, 

+												  vlan=network_port2_vlan)        

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

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

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port1_phy_port, 

+												  vlan=network_port1_vlan)        

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

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

+        

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

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

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

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

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

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

+

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport1, 

+                                                src_ip=network_port1_sip, dst_ip=network_port1_dip,

+                                                next_hop_id=network_port1_next_hop_id, 

+                                                vnid=vnid)												

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

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

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport2, 

+                                                src_ip=network_port2_sip, dst_ip=network_port2_dip,

+                                                next_hop_id=network_port2_next_hop_id, 

+                                                vnid=vnid)												

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

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

+

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

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

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

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

+        #add network mac

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

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

+

+        #add termination table for network port

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

+                             dst_mac=switch_cpu_mac, vlanid=network_port1_vlan)

+        add_termination_flow(self.controller, in_port=network_port2_phy_port, eth_type=0x0800,

+                             dst_mac=switch_cpu_mac, vlanid=network_port2_vlan)                             

+        #add vlan table for network port rx packet class vlan

+        add_one_vlan_table_flow(self.controller, of_port=network_port1_phy_port, 

+                                vlan_id=network_port1_vlan)        

+        add_one_vlan_table_flow(self.controller, of_port=network_port2_phy_port, 

+                                vlan_id=network_port2_vlan)        

+        

+        #packet tx on network port 1 rx on network port 2

+        inner_pkt = simple_udp_packet(pktlen=96, eth_dst=network_lport2_mac_str)

+        vxlan_pkt = simple_vxlan_packet(eth_dst=switch_cpu_mac_str,

+                                        vnid=vnid, 

+                                        ip_dst= network_port1_sip, 

+                                        ip_src=network_port1_dip,

+                                        inner_payload=inner_pkt)

+        self.dataplane.send(network_port1_phy_port, str(vxlan_pkt))        

+        #verify     

+        verify_packet(self, str(inner_pkt), network_port2_phy_port)

+        verify_no_other_packets(self)

+

+        

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)   

+        

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

+												vlan=access_port1_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+          

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport1, 

+												src_ip=network_port1_sip, dst_ip=network_port1_dip, 

+												next_hop_id=network_port1_next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport2, 

+												src_ip=network_port2_sip, dst_ip=network_port2_dip, 

+												next_hop_id=network_port2_next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=network_port1_next_hop_id, 

+		                                          dst_mac=network_port1_dst_mac, 

+												  phy_port=network_port1_phy_port, 

+												  vlan=network_port1_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=network_port2_next_hop_id, 

+		                                          dst_mac=network_port2_dst_mac, 

+												  phy_port=network_port2_phy_port, 

+												  vlan=network_port2_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port1_phy_port, 

+												  vlan=network_port1_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        
\ No newline at end of file
diff --git a/Fabric/Utilities/acctonUseDpctl/allow_all_ucast_route.py b/Fabric/Utilities/acctonUseDpctl/allow_all_ucast_route.py
new file mode 100755
index 0000000..3e8d1c0
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/allow_all_ucast_route.py
@@ -0,0 +1,83 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+"""	

+    [Allow all VLAN and unicast route]																				

+		Whatever incoming VLAN tag, do unicast route and output to specified port																			

+																					

+	Inject	eth 1/3	Tag3, SA000000112233, DA000000113355, SIP 192.168.1.100, DIP 192.168.2.2																		

+	Output	eth 1/1	Tag2, SA 000004223355, DA 000004224466																		

+																					

+	dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1000/0x1000 goto:20																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x20000001 goto:60																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x30003 group=any,port=any,weight=0 pop_vlan,output=3																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=501 vlan_vid=3,eth_dst=00:00:00:11:22:33 write:group=0x30003 goto:60																				

+"""

+

+class test1(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+		

+        test_ports = sorted(config["port_map"].keys())	

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1000/0x1000 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x20000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x20000001 goto:60")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(input_port)+" group=any,port=any,weight=0 pop_vlan,output="+str(input_port))

+        apply_dpctl_mod(self, config, "flow-mod table=50,cmd=add,prio=501 vlan_vid=3,eth_dst=00:00:00:11:22:33 write:group=0x3000"+str(input_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 52 00 01 00 00 40 06 f5 ee c0 a8 '

+                '01 64 c0 a8 02 02 04 d2 00 50 00 00 00 00 00 00 '

+                '00 00 50 02 20 00 6c 46 00 00 44 44 44 44 44 44 '

+                '44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 '

+                '44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 '

+                '44 44 44 44')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '08 00 45 00 00 52 00 01 00 00 3f 06 f6 ee c0 a8 '

+                '01 64 c0 a8 02 02 04 d2 00 50 00 00 00 00 00 00 '

+                '00 00 50 02 20 00 6c 46 00 00 44 44 44 44 44 44 '

+                '44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 '

+                '44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 '

+                '44 44 44 44')

+        

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        

+        

+        

+        

+        

+        
\ No newline at end of file
diff --git a/Fabric/Utilities/acctonUseDpctl/basic.py b/Fabric/Utilities/acctonUseDpctl/basic.py
new file mode 100755
index 0000000..32dfa6f
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/basic.py
@@ -0,0 +1,87 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+

+

+class features(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        json_result = apply_dpctl_get_cmd(self, config, "features")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        #self.assertTrue(result["tabs"]==64, "Table size is not correct")

+        self.assertNotEqual(result["caps"], 0, "Invalid capabilities")

+

+class get_config(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        json_result = apply_dpctl_get_cmd(self, config, "get-config")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["conf"], {}, "Config reply nothing")

+

+class desc(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        json_result = apply_dpctl_get_cmd(self, config, "stats-desc")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["mfr"], {}, "DESC MFR reply nothing")

+

+class port_desc(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "port-desc")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["port"], {}, "Port DESC reply nothing")

+

+class table_features(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "table-features")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["table_features"], {}, "Table features reply nothing")

+

+class group_features(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "group-features")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["types"], 0, "Not support group types")

+

+class meter_features(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "meter-features")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]["features"][0]

+        self.assertNotEqual(result["max_meter"], 0, "Not support meter")

+

+

diff --git a/Fabric/Utilities/acctonUseDpctl/meter.py b/Fabric/Utilities/acctonUseDpctl/meter.py
new file mode 100755
index 0000000..700eba4
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/meter.py
@@ -0,0 +1,279 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+

+"""

+Not verify yet, need to think how to verify meter

+"""

+

+class dscp(base_tests.SimpleDataPlane):

+    """

+    [DSCP meter]

+      DSCP meter

+

+    Inject  eth 1/3 {DA000000113355, SA000000112233, Tag 2} pkt [100* 10 pkt/sec]

+    Output  eth 1/1 [10] no change

+

+    Inject  eth 1/3 {DA000000113355, SA000000112233, Tag 2} pkt [100 bytes, 10 burst]

+    Output  eth 1/1 [8] no change; [2] dscp 2

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 meter-mod cmd=add,flags=0x06,meter=1 dscp_remark:rate=5,prec_level=2,burst=5

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x20001 meter:1

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "meter-mod cmd=add,flags=0x06,meter=1 dscp_remark:rate=5,prec_level=2,burst=5")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x2000"+str(output_port)+" meter:1")

+

+        input_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2)

+

+        output_pkt = input_pkt

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class drop(base_tests.SimpleDataPlane):

+    """

+    [Drop meter]

+        Drop meter

+

+    Inject  eth 1/3 {DA000000113355, SA000000112233, Tag 2} pkt [100 bytes, 10 pkt/sec]

+    Output  eth 1/1 [8] output

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 meter-mod cmd=add,flags=0x01,meter=1 drop:rate=8

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x20001 meter:1

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "meter-mod cmd=add,flags=0x01,meter=1 drop:rate=8")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x2000"+str(output_port)+" meter:1")

+

+        input_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2)

+

+        output_pkt = input_pkt

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class trtcm(base_tests.SimpleDataPlane):

+    """

+    [TrTCM meter]

+        TrTCM meter

+

+    Inject  eth 1/3 {DA000000113355, SA000000112233, Tag 2} pkt [100 bytes, 50 pkt/sec]

+    Output  eth 1/1 [16] vlan pcp 1 + [14] vlan pcp 3 + [20] vlan pcp 5

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 meter-mod cmd=add,flags=0x6,meter=1 set_color:rate=10,burst=5,exp_id=0x1018,exp_type=3,mode=1,color_aware=0,color=1 set_color:rate=20,burst=10,exp_id=0x1018,exp_type=3,mode=1,color_aware=0,color=2

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x20001 apply:set_field=ofdpa_color_actions_index:1 goto:65 meter:1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=2,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:5

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=1,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:3

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=0,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:1

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "meter-mod cmd=add,flags=0x6,meter=1 set_color:rate=10,burst=5,exp_id=0x1018,exp_type=3,mode=1,color_aware=0,color=1 set_color:rate=20,burst=10,exp_id=0x1018,exp_type=3,mode=1,color_aware=0,color=2")

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x2000"+str(output_port)+" apply:set_field=ofdpa_color_actions_index:1 goto:65 meter:1")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=2,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:5")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=1,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:3")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=0,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:1")

+

+        input_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2,

+                                      vlan_pcp=0)

+

+        output_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2,

+                                      vlan_pcp=1)

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class srtcm(base_tests.SimpleDataPlane):

+    """

+    [SrTCM meter]

+        SrTCM meter

+

+    Inject  eth 1/3 {DA000000113355, SA000000112233, Tag 2} pkt [100 bytes, 50 pkt/sec]

+    Output  eth 1/1 [15] vlan pcp 1 + [15] vlan pcp 3 + [20] vlan pcp 5

+

+    Inject  eth 1/3 {DA000000113355, SA000000112233, Tag 2} pkt [100 bytes, 30 pkt/sec]

+    Output  eth 1/1 [15] vlan pcp 1 + [15] vlan pcp 3

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 meter-mod cmd=add,flags=0x6,meter=1 set_color:rate=10,exp_id=0x1018,exp_type=3,mode=2,color_aware=0,color=1,burst=10 set_color:rate=20,exp_id=0x1018,exp_type=3,mode=2,color_aware=0,color=2,burst=20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x20001 apply:set_field=ofdpa_color_actions_index:1 goto:65 meter:1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=2,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:5

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=1,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:3

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=0,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:1

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "meter-mod cmd=add,flags=0x6,meter=1 set_color:rate=10,exp_id=0x1018,exp_type=3,mode=2,color_aware=0,color=1,burst=10 set_color:rate=20,exp_id=0x1018,exp_type=3,mode=2,color_aware=0,color=2,burst=20")

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x2000"+str(output_port)+" apply:set_field=ofdpa_color_actions_index:1 goto:65 meter:1")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=2,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:5")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=1,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:3")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=0,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:1")

+

+        input_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2,

+                                      vlan_pcp=0)

+

+        output_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2,

+                                      vlan_pcp=1)

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class mod_trtcm(base_tests.SimpleDataPlane):

+    """

+    [Mod TrTCM meter]

+        Mod TrTCM meter

+

+    Inject  eth 1/3 {DA000000113355, SA000000112233, Tag 2} pkt [100 bytes, 50 pkt/sec]

+    Output  eth 1/1  [15] vlan pcp 1 + [28] vlan pcp 3 + [7] vlan pcp 5

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 meter-mod cmd=add,flags=0x6,meter=1 set_color:rate=10,burst=5,exp_id=0x1018,exp_type=3,mode=3,color_aware=0,color=1 set_color:rate=20,burst=10,exp_id=0x1018,exp_type=3,mode=3,color_aware=0,color=2

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x20001 apply:set_field=ofdpa_color_actions_index:1 goto:65 meter:1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=2,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:5

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=1,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:3

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=0,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:1

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "meter-mod cmd=add,flags=0x6,meter=1 set_color:rate=10,burst=5,exp_id=0x1018,exp_type=3,mode=3,color_aware=0,color=1 set_color:rate=20,burst=10,exp_id=0x1018,exp_type=3,mode=3,color_aware=0,color=2")

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x2000"+str(output_port)+" apply:set_field=ofdpa_color_actions_index:1 goto:65 meter:1")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=2,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:5")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=1,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:3")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=0,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:1")

+

+        input_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2,

+                                      vlan_pcp=0)

+

+        output_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2,

+                                      vlan_pcp=1)

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+

diff --git a/Fabric/Utilities/acctonUseDpctl/mpls.py b/Fabric/Utilities/acctonUseDpctl/mpls.py
new file mode 100755
index 0000000..a4399d7
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/mpls.py
@@ -0,0 +1,1100 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+import time

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+

+class encap_mpls(base_tests.SimpleDataPlane):

+    """

+    [Encap one MPLS label]

+      Encap a MPLS label

+

+    Inject  eth 1/3 Tag 3, SA000000112233, DA000000113355, V4

+    Output  eth 1/1 Tag 2, SA000004223355, DA000004224466, MPLS label 2305, EXP7, BoS1, TTL250, CW

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x20001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3 apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x2000"+str(output_port)+" goto:60")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+" apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(output_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(output_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 1f fa 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 03 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b2 47 c0 a8 01 64 c0 a8 02 02 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_mpls(base_tests.SimpleDataPlane):

+    """

+    [Decap one MPLS label]

+      Decap the MPLS label

+

+    Inject  eth 1/1 Tag 2, SA000004223355, DA000004224466, MPLS label 2305, EXP7, BoS1, TTL250, CW, InSA000000112233, InDA000000113355

+    Output  eth 1/3 SA000000112233, DA000000113355

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x20001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3 apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(input_port)+" group=any,port=any,weight=0 output="+str(input_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x2000"+str(input_port)+" goto:60")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(output_port)+" apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 1f fa 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 05 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 05 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 '

+                '02 01 c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 '

+                '0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 '

+                '00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class encap_2mpls(base_tests.SimpleDataPlane):

+    """

+    [Encap two MPLS labels]

+      Encap two MPLS labels

+

+    Inject  eth 1/3 Tag 3, SA000000112233, DA000000113355

+    Output  eth 1/1 Tag 2, Outer label 0x903, TTL 250, InLabel 0x901, TTL 250, SA000004223355, DA000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x20001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x903,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x93000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x2000"+str(output_port)+" goto:60")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x903,group=0x90000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x93000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 3e fa 00 90 1f fa 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 03 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 01 64 '

+                'c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class encap_3mpls(base_tests.SimpleDataPlane):

+    """

+    [Encap 3 MPLS labels]

+      Encap 3 MPLS labels

+

+    Inject  eth 1/3 Tag 3, SA000000112233, DA000000113355

+    Output  eth 1/1 Tag 2, Outest label 0x904, TTL 250, Middle label 0x903, InLabel 0x901, SA000004223355, DA000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x20001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x94000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x904,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x903,group=0x94000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x93000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x2000"+str(output_port)+" goto:60")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x94000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x904,group=0x90000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x903,group=0x94000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x93000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 4e fa 00 90 3e fa 00 90 1f fa 00 00 '

+                '00 00 00 00 00 11 33 55 00 00 00 11 22 33 81 00 '

+                '00 03 08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 '

+                'c0 a8 01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_penultimate_mpls(base_tests.SimpleDataPlane):

+    """

+    [Penultimate Hop Pop]

+      Pop outermost tunnel label

+

+    Inject  eth 1/1 Tag 2, Outer label 0x901, InLabel 0xF, SA000004223355, DA000004224466

+    Output  eth 1/3 Tag 2, label 0xF, SA000004223355, DA000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901 apply:pop_mpls=0x8847,mpls_dec write:group=0x90000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901 apply:pop_mpls=0x8847,mpls_dec write:group=0x90000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 1e fa 00 01 0b ff 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 05 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 02 01 '

+                'c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 0a 0b '

+                '0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 01 0f f9 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 05 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_2mpls(base_tests.SimpleDataPlane):

+    """

+    [Pop, decap, and L2 forward]

+      Pop outermost tunnel label and pop outer L2 header (L2 Switch VPWS )

+

+    Inject  eth 1/1 Tag 2, Outer label 0x903, InLabel 0x901, SA000004223355, DA000004224466; InTag 5, InSA000000112233, InDA000000113355

+    Output  eth 1/3 Tag 5, SA000000112233, DA000000113355

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 set_field=mpls_label:0x903,push_mpls=0x8847,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x93000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x00008847 goto:24

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec goto:24

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x20001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(input_port)+" group=any,port=any,weight=0 output="+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 set_field=mpls_label:0x903,push_mpls=0x8847,group=0x90000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x93000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(output_port)+",vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x00008847 goto:24")

+        apply_dpctl_mod(self, config, "flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec goto:24")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x2000"+str(input_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 3e fa 00 90 1b ff 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 05 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 02 01 '

+                'c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 0a 0b '

+                '0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        output_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 05 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 '

+                '02 01 c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 '

+                '0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_penultimate_swap_mpls(base_tests.SimpleDataPlane):

+    """

+    [Penultimate Hop Pop and swap inner MPLS label]

+      Pop outermost tunnel label and swap inner MPLS label (MS-PW, LSR)

+

+    Inject  eth 1/1 Tag 2, Outer label 0x903, InLabel 0x901, SA000004223355, DA000004224466; InTag 5, InSA000000112233, InDA000000113355

+    Output  eth 1/3 Tag 2, Label 0x905, TTL 249, SA000004223355, DA000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec goto:24

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x905,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:mpls_dec write:group=0x95000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec goto:24")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x905,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:mpls_dec write:group=0x95000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 3e fa 00 90 1b ff 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 05 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 02 01 '

+                'c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 0a 0b '

+                '0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 51 f9 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 05 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+

+class swap_out_mpls(base_tests.SimpleDataPlane):

+    """

+    [Swap outermost MPLS label]

+      Swap outermost MPLS label (LSR)

+

+    Inject  eth 1/1 Tag 2, Outer label 0x901, TTL 250, InLabel 0xF, DA000004223355, SA000004224466

+    Output  eth 1/3 Tag 2, Outer label 0x9051, TTL 249, InLabel 0xF, SA000004223357, DA000004224467

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:57,set_field=eth_dst=00:00:04:22:44:67,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x9051,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901 apply:mpls_dec write:group=0x95000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:57,set_field=eth_dst=00:00:04:22:44:67,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x9051,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901 apply:mpls_dec write:group=0x95000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 1e fa 00 01 0b ff 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 05 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 02 01 '

+                'c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 0a 0b '

+                '0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 67 00 00 04 22 33 57 81 00 00 02 '

+                '88 47 09 05 10 f9 00 01 0b ff 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 05 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 02 01 '

+                'c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 0a 0b '

+                '0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+

+class swap_encap_mpls(base_tests.SimpleDataPlane):

+    """

+    [Swap and encap a MPLS label]

+      Swap and encap a MPLS label

+

+    Inject  eth 1/1 Tag 2, MPLS label 0x901, TTL 250, DA000004223355, SA000004224466

+    Output  eth 1/3 Tag 2, Outer label 0x9052, TTL 249, InLabel 0xF, SA000004223358, DA000004224468

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:58,set_field=eth_dst=00:00:04:22:44:68,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x9052,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:mpls_dec write:group=0x95000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:58,set_field=eth_dst=00:00:04:22:44:68,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x9052,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:mpls_dec write:group=0x95000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 1f fa 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 05 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 68 00 00 04 22 33 58 81 00 00 02 '

+                '88 47 09 05 21 f9 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 05 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class swap_encap_2mpls(base_tests.SimpleDataPlane):

+    """

+    [Swap and encap 2 MPLS labels]

+      Swap and encap 2 MPLS labels

+

+    Inject  eth 1/1 Tag 2, MPLS label 0x901, TTL 250, DA000004223355, SA000004224466

+    Output  eth 1/3 Tag 2, Outest label 0x904, TTL 249, Middle label 0x903, InLabel 0x9052, SA000004223358, DA000004224468

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:58,set_field=eth_dst=00:00:04:22:44:68,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x94000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x904,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x903,group=0x94000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x9052,group=0x93000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:mpls_dec write:group=0x95000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:58,set_field=eth_dst=00:00:04:22:44:68,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x94000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x904,group=0x90000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x903,group=0x94000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x9052,group=0x93000001")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:mpls_dec write:group=0x95000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 1f fa 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 05 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 68 00 00 04 22 33 58 81 00 00 02 '

+                '88 47 00 90 40 f9 00 90 30 f9 09 05 21 f9 00 00 '

+                '00 00 00 00 00 11 33 55 00 00 00 11 22 33 81 00 '

+                '00 05 08 00 45 00 00 2e 04 d2 00 00 7f 00 b1 aa '

+                'c0 a8 02 01 c0 a8 02 02 00 01 02 03 04 05 06 07 '

+                '08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 '

+                '18 19 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_1mpls_of3(base_tests.SimpleDataPlane):

+    """

+    [Decap outermost MPLS label of 3 MPLS labels]

+      Decap outermost one MPLS of 3 MPLS labels

+

+    Inject  eth 1/1 Tag 2, Outest label 0x904, TTL 250, Middle label 0x903/250, InLabel 0x901/250, SA000004224466, DA000004223355

+    Output  eth 1/3 Tag 2, Outer label 0x903/249, InLabel 0x901/250, SA000004223355, DA000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x904 apply:pop_mpls=0x8847,mpls_dec write:group=0x90000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x904 apply:pop_mpls=0x8847,mpls_dec write:group=0x90000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 4e fa 00 90 3e fa 00 90 1f fa 00 00 '

+                '00 00 00 00 00 11 33 55 00 00 00 11 22 33 00 00 '

+                '00 03 08 00 45 00 00 2e 04 d2 00 00 7f 00 b1 aa '

+                'c0 a8 02 01 c0 a8 02 02 00 01 02 03 04 05 06 07 '

+                '08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 '

+                '18 19')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 3e f9 00 90 1f fa 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 00 00 00 03 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 02 01 '

+                'c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 0a 0b '

+                '0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_2mpls_of3(base_tests.SimpleDataPlane):

+    """

+    [Decap outermost 2 MPLS labels of 3 MPLS labels]

+      Decap outermost two MPLS of 3 MPLS labels

+

+    Inject  eth 1/1 Tag 2, Outest label 0x904, TTL 250, Middle label 0x903/250, InLabel 0x901/250, SA000004224466, DA000004223355

+    Output  eth 1/3 Tag 2, MPLS Label 0x901/249, SA000004223355, DA000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x904 apply:pop_mpls=0x8847,mpls_dec goto:24

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec write:group=0x90000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x904 apply:pop_mpls=0x8847,mpls_dec goto:24")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec write:group=0x90000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 4e fa 00 90 3e fa 00 90 1f fa 00 00 '

+                '00 00 00 00 00 11 33 55 00 00 00 11 22 33 00 00 '

+                '00 03 08 00 45 00 00 2e 04 d2 00 00 7f 00 b1 aa '

+                'c0 a8 02 01 c0 a8 02 02 00 01 02 03 04 05 06 07 '

+                '08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 '

+                '18 19')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 1f f9 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 00 00 00 03 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class encap_2mpls_ff(base_tests.SimpleDataPlane):

+    """

+    [Encap two MPLS labels with FF]

+      Encap two MPLS labels with fast failover group

+

+    Env eth 1/1 link up; eth 1/5 link down

+    Inject  eth 1/3 Tag 3, SA000000112233, DA000000113355

+    Output  eth 1/1 Tag 2, Outest label 0x931, TTL 250, InLabel 0x901, SA000004223351, DA000004224461

+

+    Env eth 1/1 link down; eth 1/5 link up

+    Inject  eth 1/3 Tag 3, SA000000112233, DA000000113355

+    Output  eth 1/5 Tag 2, Outest label 0x935, TTL 250, InLabel 0x901, SA000004223355, DA000004224465

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:51,set_field=eth_dst=00:00:04:22:44:61,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x931,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20005 group=any,port=any,weight=0 output=5

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000005 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:65,set_field=vlan_vid=2,group=0x20005

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000005 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x935,group=0x90000005

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ff,group=0xA6000001 group=any,port=1,weight=0 group=0x93000001 group=any,port=5,weight=0 group=0x93000005

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0xA6000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x20001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+        

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:51,set_field=eth_dst=00:00:04:22:44:61,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x931,group=0x90000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port2)+" group=any,port=any,weight=0 output="+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000005 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:65,set_field=vlan_vid=2,group=0x2000"+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000005 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x935,group=0x90000005")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ff,group=0xA6000001 group=any,port="+str(output_port)+",weight=0 group=0x93000001 group=any,port="+str(output_port2)+",weight=0 group=0x93000005")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0xA6000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x2000"+str(output_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 61 00 00 04 22 33 51 81 00 00 02 '

+                '88 47 00 93 1e fa 00 90 1f fa 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 03 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 01 64 '

+                'c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt2 = simple_packet(

+                '00 00 04 22 44 65 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 93 5e fa 00 90 1f fa 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 03 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 01 64 '

+                'c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+        #if output_port link down

+        apply_dpctl_mod(self, config, "port-mod port="+str(output_port)+",conf=0x1,mask=0x1")

+        time.sleep(1)

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt2), output_port2)

+        apply_dpctl_mod(self, config, "port-mod port="+str(output_port)+",conf=0x0,mask=0x1")

+        #make sure port link up        

+        port_up = 0

+        while port_up == 0:

+            time.sleep(1)

+            #apply_dpctl_mod(self, config, "port-mod port="+str(output_port)+",conf=0x0,mask=0x1")

+            json_result = apply_dpctl_get_cmd(self, config, "port-desc")

+            result=json_result["RECEIVED"][1]

+            for p_desc in result["port"]:

+                if p_desc["no"] == output_port:

+                    if p_desc["config"] != 0x01 : #up                        

+                        port_up = 1

+                                

+

+

+class decap_mpls_acl(base_tests.SimpleDataPlane):

+    """

+    [Decap a MPLS label with ACL]

+      Decap a MPLS label with ACL

+

+    Inject  eth 1/1 Tag 2, SA000004223355, DA000004224466, MPLS label 2305, EXP7, BoS1, TTL250, CW, InSA000000112233, InDA000000113355

+    Output  eth 1/5 SA000000112233, DA000000113355

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x20001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3 apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20005 group=any,port=any,weight=0 output=5

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 tunn_id=0x10001,ofdpa_mpls_l2_port=131328 write:group=0x20005

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(input_port)+" group=any,port=any,weight=0 output="+str(input_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x2000"+str(input_port)+" goto:60")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+" apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 tunn_id=0x10001,ofdpa_mpls_l2_port=131328 write:group=0x2000"+str(output_port))

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 1f fa 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 05 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 05 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 '

+                '02 01 c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 '

+                '0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 '

+                '00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class encap_mpls_l3(base_tests.SimpleDataPlane):

+    """

+    [Encap a MPLS label with L3]

+      Encap a MPLS label with L3 routing

+

+    Inject  eth 1/3 Tag 2, SA000000112233, DA000000113355, SIP 192.168.1.10, DIP 192.168.2.2

+    Output  eth 1/1 SA000004223355, DA000004224466, Tag2, MPLS label 0x901; IP the same as original

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=2/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x92000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ttl_out,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x92000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x92000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ttl_out,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x92000001 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b0 81 c0 a8 '

+                '03 0a c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 1f fa 45 00 00 4e 04 d2 00 00 7e 00 '

+                'b1 81 c0 a8 03 0a c0 a8 02 02 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_mpls_l3(base_tests.SimpleDataPlane):

+    """

+    [Decap a MPLS label with L3]

+      Decap a MPLS label with L3 routing

+

+    Inject  eth 1/3 Tag 12, SA000000112233, DA000000000111, MPLS 0x1234, SIP 192.168.3.1, DIP 192.168.2.1

+    Output  eth 1/1 Tag 10, SA000006223355, DA000006224466, SIP 192.168.3.1, DIP 192.168.2.1

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x100c/0x1fff apply:set_field=ofdpa_vrf:1 goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0xa0001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20000001 group=any,port=any,weight=0 set_field=eth_src=00:00:06:22:33:55,set_field=eth_dst=00:00:06:22:44:66,set_field=vlan_vid=10,group=0xa0001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x1234,mpls_bos=1,ofdpa_mpls_data_first_nibble=4 apply:mpls_dec,pop_mpls=0x0800,set_field=ofdpa_vrf:1 goto:30

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.3.2/255.255.255.0,ofdpa_vrf=1 write:group=0x20000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=12/0xfff,eth_dst=00:00:00:00:01:11,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x100c/0x1fff apply:set_field=ofdpa_vrf:1 goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0xa000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x20000001 group=any,port=any,weight=0 set_field=eth_src=00:00:06:22:33:55,set_field=eth_dst=00:00:06:22:44:66,set_field=vlan_vid=10,group=0xa000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x1234,mpls_bos=1,ofdpa_mpls_data_first_nibble=4 apply:mpls_dec,pop_mpls=0x0800,set_field=ofdpa_vrf:1 goto:30")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.3.2/255.255.255.0,ofdpa_vrf=1 write:group=0x20000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=12/0xfff,eth_dst=00:00:00:00:01:11,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 00 00 01 11 00 00 00 11 22 33 81 00 00 0c '

+                '88 47 01 23 41 3f 45 00 00 26 00 00 00 00 3f 00 '

+                'f5 84 c0 a8 02 01 c0 a8 03 02 00 01 02 03 04 05 '

+                '06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 '

+                '16 17 18 19')

+

+        output_pkt = simple_packet(

+                '00 00 06 22 44 66 00 00 06 22 33 55 81 00 00 0a '

+                '08 00 45 00 00 26 00 00 00 00 3e 00 f6 84 c0 a8 '

+                '02 01 c0 a8 03 02 00 01 02 03 04 05 06 07 08 09 '

+                '0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class encap_2mpls_l3(base_tests.SimpleDataPlane):

+    """

+    [Encap two MPLS labels with L3]

+      Encap two MPLS labels with L3 routing

+

+    Inject  eth 1/3 Tag 2, SA000000112233, DA000000113355, SIP 192.168.1.10, DIP 192.168.2.2

+    Output  eth 1/1 SA000004223355, DA000004224466, Tag2, Outer Label 0x903, EXP 7, TTL 250, Inner Label 0x901, EXP 7, TTL 250; IP the same as original

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=2/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 set_field=mpls_label:0x903,push_mpls=0x8847,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x92000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ttl_out,group=0x93000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x92000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 set_field=mpls_label:0x903,push_mpls=0x8847,group=0x90000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x92000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ttl_out,group=0x93000001")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x92000001 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b0 81 c0 a8 '

+                '03 0a c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 3e fa 00 90 1f fa 45 00 00 4e 04 d2 '

+                '00 00 7e 00 b1 81 c0 a8 03 0a c0 a8 02 02 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_2mpls_l3(base_tests.SimpleDataPlane):

+    """

+    [Decap two MPLS labels with L3]

+      Decap two MPLS labels with L3 routing

+

+    Inject  eth 1/1 SA000004223355, DA000004224466, Tag2, Outer Label 0x903, EXP 7, TTL 250, Inner Label 0x901, SIP 192.168.3.2, DIP 192.168.2.10

+    Output  eth 1/3 SA000006223355, DA000006224466, Tag2, SIP 192.168.3.2, DIP 192.168.2.10

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20000003 group=any,port=any,weight=0 set_field=eth_src=00:00:06:22:33:55,set_field=eth_dst=00:00:06:22:44:66,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff apply:set_field=ofdpa_vrf:1 goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec goto:24

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1,ofdpa_mpls_data_first_nibble=4 apply:mpls_dec,pop_mpls=0x0800,set_field=ofdpa_vrf:1 goto:30

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0,ofdpa_vrf=1 write:group=0x20000003 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x20000003 group=any,port=any,weight=0 set_field=eth_src=00:00:06:22:33:55,set_field=eth_dst=00:00:06:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff apply:set_field=ofdpa_vrf:1 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+        apply_dpctl_mod(self, config, "flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec goto:24")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1,ofdpa_mpls_data_first_nibble=4 apply:mpls_dec,pop_mpls=0x0800,set_field=ofdpa_vrf:1 goto:30")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0,ofdpa_vrf=1 write:group=0x20000003 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 3e fa 00 90 1f fa 45 00 00 26 00 00 '

+                '00 00 7e 06 b6 75 c0 a8 03 02 c0 a8 02 0a 00 03 '

+                '00 06 00 01 f7 fa 00 00 00 00 50 00 04 00 2f 5d '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 06 22 44 66 00 00 06 22 33 55 81 00 00 02 '

+                '08 00 45 00 00 26 00 00 00 00 f9 06 3b 75 c0 a8 '

+                '03 02 c0 a8 02 0a 00 03 00 06 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 2f 5d 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class encap_3mpls_l3(base_tests.SimpleDataPlane):

+    """

+    [Encap 3 MPLS labels with L3]

+      Encap 3 MPLS labels with L3 routing

+

+    Inject  eth 1/3 Tag 2, SA000000112233, DA000000113355, SIP 192.168.1.10, DIP 192.168.2.2

+    Output  eth 1/1 SA000004223355, DA000004224466, Tag2, OuterLabel 0x904 EXP 7, TTL 250, M 0x903, Inner0x901, EXP 7, TTL 250; IP the same as original

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=2/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x94000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x904,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 set_field=mpls_label:0x903,push_mpls=0x8847,group=0x94000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x92000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ttl_out,group=0x93000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x92000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x94000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x904,group=0x90000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 set_field=mpls_label:0x903,push_mpls=0x8847,group=0x94000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x92000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ttl_out,group=0x93000001")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x92000001 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b0 81 c0 a8 '

+                '03 0a c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 4e fa 00 90 3e fa 00 90 1f fa 45 00 '

+                '00 4e 04 d2 00 00 7e 00 b1 81 c0 a8 03 0a c0 a8 '

+                '02 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

diff --git a/Fabric/Utilities/acctonUseDpctl/nat.py b/Fabric/Utilities/acctonUseDpctl/nat.py
new file mode 100755
index 0000000..04f267a
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/nat.py
@@ -0,0 +1,400 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+

+

+class dnat(base_tests.SimpleDataPlane):

+    """

+    [DNAT]

+      DNAT (inbound)

+

+    Inject  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 200.0.0.1, DIP 100.0.0.01, Sport 2828, Dport 5000

+    Output  eth 1/1 DA000000000101, SA000000000100, Tag 100, SIP 200.0.0.1, DIP 10.0.0.01, Sport 2828, Dport 2000

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x10c8/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x640001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x640001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x23000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x10c8/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x64000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x64000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28")

+        apply_dpctl_mod(self, config, "flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x23000001 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 00 02 00 00 00 00 00 02 01 81 00 00 c8 '

+                '08 00 45 00 00 2a 04 d2 00 00 7f 06 0a fa c8 00 '

+                '00 01 64 00 00 01 0b 0c 13 88 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 69 50 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 00 01 01 00 00 00 00 01 00 81 00 00 64 '

+                '08 00 45 00 00 2a 04 d2 00 00 7e 06 65 fa c8 00 '

+                '00 01 0a 00 00 01 0b 0c 07 d0 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 cf 08 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class dnat_vrf(base_tests.SimpleDataPlane):

+    """

+    [DNAT VRF]

+      DNAT (inbound) with specified VRF

+

+    Inject  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 200.0.0.1, DIP 100.0.0.01, Sport 2828, Dport 5000

+    Output  eth 1/1 DA000000000101, SA000000000100, Tag 100, SIP 200.0.0.1, DIP 10.0.0.01, Sport 2828, Dport 2000

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x10c8/0x1fff goto:20 apply:set_field=ofdpa_vrf:3

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1064/0x1fff goto:20 apply:set_field=ofdpa_vrf:3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x640001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x640001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000,ofdpa_vrf=3 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x23000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x10c8/0x1fff goto:20 apply:set_field=ofdpa_vrf:3")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(output_port)+",vlan_vid=0x1064/0x1fff goto:20 apply:set_field=ofdpa_vrf:3")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x64000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x64000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28")

+        apply_dpctl_mod(self, config, "flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000,ofdpa_vrf=3 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x23000001 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 00 02 00 00 00 00 00 02 01 81 00 00 c8 '

+                '08 00 45 00 00 2a 04 d2 00 00 7f 06 0a fa c8 00 '

+                '00 01 64 00 00 01 0b 0c 13 88 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 69 50 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 00 01 01 00 00 00 00 01 00 81 00 00 64 '

+                '08 00 45 00 00 2a 04 d2 00 00 7e 06 65 fa c8 00 '

+                '00 01 0a 00 00 01 0b 0c 07 d0 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 cf 08 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+"""

+currently this case will fail, due to packet rx SRC IP problem

+"""

+class dnat_ecmp(base_tests.SimpleDataPlane):

+    """

+    [DNAT ECMP]

+      DNAT (inbound) with ECMP

+

+    Inject  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 200.0.0.1, DIP 100.0.0.01, Sport 2828, Dport 5000 [increase SIP]

+    Output  eth 1/1 DA000000000101, SA000000000100, Tag 100, SIP 200.0.0.X, DIP 10.0.0.01, Sport 2828, Dport 2000

+    Output  eth 1/5 DA000005224466, SA000005223355, Tag 2, SIP 200.0.0.X, DIP 10.0.0.01, Sport 2828, Dport 2000

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x10c8/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x640001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x640001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20005 group=any,port=any,weight=0 output=5

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000005 group=any,port=any,weight=0 set_field=eth_src=00:00:05:22:33:55,set_field=eth_dst=00:00:05:22:44:66,set_field=vlan_vid=2,group=0x20005

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=sel,group=0x71000001 group=any,port=any,weight=0 group=0x23000001 group=any,port=any,weight=0 group=0x23000005

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x71000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x10c8/0x1fff goto:20 apply:set_field=ofdpa_vrf:3")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x64000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x64000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port2)+" group=any,port=any,weight=0 output="+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x23000005 group=any,port=any,weight=0 set_field=eth_src=00:00:05:22:33:55,set_field=eth_dst=00:00:05:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=sel,group=0x71000001 group=any,port=any,weight=0 group=0x23000001 group=any,port=any,weight=0 group=0x23000005")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28")

+        apply_dpctl_mod(self, config, "flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x71000001 goto:60")

+

+        #increased SIP

+        input_pkt = simple_packet(

+                '00 00 00 00 02 00 00 00 00 00 02 01 81 00 00 c8 '

+                '08 00 45 00 00 2a 04 d2 00 00 7f 06 0a fa c8 00 '

+                '00 01 64 00 00 01 0b 0c 13 88 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 69 50 00 00 00 00')

+

+        #random SIP

+        output_pkt = simple_packet(

+                '00 00 00 00 01 01 00 00 00 00 01 00 81 00 00 64 '

+                '08 00 45 00 00 2a 04 d2 00 00 7e 06 65 ee c8 00 '

+                '00 0d 0a 00 00 01 0b 0c 07 d0 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 ce fc 00 00 00 00')

+

+        #random SIP

+        output_pkt2 = simple_packet(

+                '00 00 05 22 44 66 00 00 05 22 33 55 81 00 00 02 '

+                '08 00 45 00 00 2a 04 d2 00 00 7e 06 65 ef c8 00 '

+                '00 0c 0a 00 00 01 0b 0c 07 d0 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 ce fd 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt2), output_port2)

+

+

+class dnat_decap_mpls(base_tests.SimpleDataPlane):

+    """

+    [Decap MPLS label and DNAT]

+      Decap MPLS label and DNAT

+

+    Inject  eth 1/3 Tag 12, SA000000112233, DA000000000111, MPLS 0x1234, SIP 200.0.0.1, DIP 100.0.0.1

+    Output  eth 1/1 DA000000000101, SA000000000100, Tag 100, SIP 200.0.0.1, DIP 10.0.0.01

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x640001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x640001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x100c/0x1fff apply:set_field=ofdpa_vrf:1 goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=12/0xfff,eth_dst=00:00:00:00:01:11,eth_type=0x8847 goto:24

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x1234,mpls_bos=1,ofdpa_mpls_data_first_nibble=4 apply:mpls_dec,pop_mpls=0x0800,set_field=ofdpa_vrf:1 goto:30

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ofdpa_vrf=1 write:set_field=ip_dst:10.0.0.1,group=0x23000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x64000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x64000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x100c/0x1fff apply:set_field=ofdpa_vrf:1 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=12/0xfff,eth_dst=00:00:00:00:01:11,eth_type=0x8847 goto:24")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x1234,mpls_bos=1,ofdpa_mpls_data_first_nibble=4 apply:mpls_dec,pop_mpls=0x0800,set_field=ofdpa_vrf:1 goto:30")

+        apply_dpctl_mod(self, config, "flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ofdpa_vrf=1 write:set_field=ip_dst:10.0.0.1,group=0x23000001 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 00 01 11 00 00 00 11 22 33 81 00 00 0c '

+                '88 47 01 23 41 3f 45 00 00 26 00 00 00 00 3f 00 '

+                '4f d6 c8 00 00 01 64 00 00 01 00 01 02 03 04 05 '

+                '06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 '

+                '16 17 18 19')

+

+        output_pkt = simple_packet(

+                '00 00 00 00 01 01 00 00 00 00 01 00 81 00 00 64 '

+                '08 00 45 00 00 26 00 00 00 00 3e 00 aa d6 c8 00 '

+                '00 01 0a 00 00 01 00 01 02 03 04 05 06 07 08 09 '

+                '0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class snat(base_tests.SimpleDataPlane):

+    """

+    [SNAT]

+      SNAT (outbound)

+

+    Inject  eth 1/1 DA000000000100, SA000000000101, Tag 100, SIP 10.0.0.1, DIP 200.0.0.01, Sport 2000, Dport 2828

+    Output  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 100.0.0.1, DIP 200.0.0.01, Sport 5000, Dport 2828

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1064/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=100/0xfff,eth_dst=00:00:00:00:01:00,eth_type=0x0800 goto:29

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0xC80003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x22000002 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:02:00,set_field=eth_dst=00:00:00:00:02:01,set_field=vlan_vid=200,group=0xC80003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=200.0.0.1/255.255.255.0 write:group=0x22000002 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1064/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=100/0xfff,eth_dst=00:00:00:00:01:00,eth_type=0x0800 goto:29")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0xC8000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x22000002 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:02:00,set_field=eth_dst=00:00:00:00:02:01,set_field=vlan_vid=200,group=0xC8000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=200.0.0.1/255.255.255.0 write:group=0x22000002 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 00 01 00 00 00 00 00 02 00 81 00 00 64 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 06 64 f6 0a 00 '

+                '00 01 c8 00 00 01 07 d0 0b 0c 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 cf 04 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 00 02 01 00 00 00 00 02 00 81 00 00 c8 '

+                '08 00 45 00 00 2e 04 d2 00 00 7e 06 0b f6 64 00 '

+                '00 01 c8 00 00 01 13 88 0b 0c 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 69 4c 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class snat_vrf(base_tests.SimpleDataPlane):

+    """

+    [SNAT VRF]

+      SNAT (outbound) with specified VRF

+

+    Inject  eth 1/1 DA000000000100, SA000000000101, Tag 100, SIP 10.0.0.1, DIP 200.0.0.01, Sport 2000, Dport 2828

+    Output  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 100.0.0.1, DIP 200.0.0.01, Sport 5000, Dport 2828

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1064/0x1fff goto:20 apply:set_field=ofdpa_vrf:3

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x10c8/0x1fff goto:20 apply:set_field=ofdpa_vrf:3

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=100/0xfff,eth_dst=00:00:00:00:01:00,eth_type=0x0800 goto:29

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0xC80003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x22000002 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:02:00,set_field=eth_dst=00:00:00:00:02:01,set_field=vlan_vid=200,group=0xC80003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000,ofdpa_vrf=3 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=200.0.0.1/255.255.255.0,ofdpa_vrf=3 write:group=0x22000002 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1064/0x1fff goto:20 apply:set_field=ofdpa_vrf:3")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x10c8/0x1fff goto:20 apply:set_field=ofdpa_vrf:3")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=100/0xfff,eth_dst=00:00:00:00:01:00,eth_type=0x0800 goto:29")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0xC8000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x22000002 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:02:00,set_field=eth_dst=00:00:00:00:02:01,set_field=vlan_vid=200,group=0xC8000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000,ofdpa_vrf=3 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=200.0.0.1/255.255.255.0,ofdpa_vrf=3 write:group=0x22000002 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 00 01 00 00 00 00 00 02 00 81 00 00 64 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 06 64 f6 0a 00 '

+                '00 01 c8 00 00 01 07 d0 0b 0c 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 cf 04 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 00 02 01 00 00 00 00 02 00 81 00 00 c8 '

+                '08 00 45 00 00 2e 04 d2 00 00 7e 06 0b f6 64 00 '

+                '00 01 c8 00 00 01 13 88 0b 0c 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 69 4c 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+"""

+currently this case will fail, due to packet rx src IP problem

+"""

+class snat_ecmp(base_tests.SimpleDataPlane):

+    """

+    [SNAT ECMP]

+      SNAT (outbound) with ECMP

+

+    Inject  eth 1/1 DA000000000100, SA000000000101, Tag 100, SIP 10.0.0.1, DIP 200.0.0.01, Sport 2000, Dport 2828 [increase DIP]

+    Output  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 100.0.0.1, DIP 200.0.0.X, Sport 5000, Dport 2828

+    Output  eth 1/5 DA000000000500, SA000000000501, Tag 5, SIP 100.0.0.1, DIP 200.0.0.X, Sport 5000, Dport 2828

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1064/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=100/0xfff,eth_dst=00:00:00:00:01:00,eth_type=0x0800 goto:29

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0xC80003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x22000002 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:02:00,set_field=eth_dst=00:00:00:00:02:01,set_field=vlan_vid=200,group=0xC80003

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x50005 group=any,port=any,weight=0 output=5

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x22000005 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:05:00,set_field=eth_dst=00:00:00:00:05:01,set_field=vlan_vid=5,group=0x50005

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=sel,group=0x71000001 group=any,port=any,weight=0 group=0x22000002 group=any,port=any,weight=0 group=0x22000005

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=200.0.0.1/255.255.255.0 write:group=0x71000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1064/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=100/0xfff,eth_dst=00:00:00:00:01:00,eth_type=0x0800 goto:29")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0xC8000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x22000002 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:02:00,set_field=eth_dst=00:00:00:00:02:01,set_field=vlan_vid=200,group=0xC8000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x5000"+str(output_port2)+" group=any,port=any,weight=0 output="+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x22000005 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:05:00,set_field=eth_dst=00:00:00:00:05:01,set_field=vlan_vid=5,group=0x5000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=sel,group=0x71000001 group=any,port=any,weight=0 group=0x22000002 group=any,port=any,weight=0 group=0x22000005")

+        apply_dpctl_mod(self, config, "flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=200.0.0.1/255.255.255.0 write:group=0x71000001 goto:60")

+

+        #increased DIP

+        input_pkt = simple_packet(

+                '00 00 00 00 01 00 00 00 00 00 02 00 81 00 00 64 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 06 64 f6 0a 00 '

+                '00 01 c8 00 00 01 07 d0 0b 0c 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 cf 04 00 00 00 00 00 00 00 00')

+

+        #rnadom DIP

+        output_pkt = simple_packet(

+                '00 00 00 00 02 01 00 00 00 00 02 00 81 00 00 c8 '

+                '08 00 45 00 00 2e 04 d2 00 00 7e 06 0b e8 64 00 '

+                '00 01 c8 00 00 0f 13 88 0b 0c 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 69 3e 00 00 00 00 00 00 00 00')

+

+        #rnadom DIP

+        output_pkt2 = simple_packet(

+                '00 00 00 00 05 01 00 00 00 00 05 00 81 00 00 05 '

+                '08 00 45 00 00 2e 04 d2 00 00 7e 06 0b f4 64 00 '

+                '00 01 c8 00 00 03 13 88 0b 0c 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 69 4a 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt2), output_port2)

diff --git a/Fabric/Utilities/acctonUseDpctl/phase1.py b/Fabric/Utilities/acctonUseDpctl/phase1.py
new file mode 100755
index 0000000..95cba29
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/phase1.py
@@ -0,0 +1,421 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+

+

+class l3ucast_route(base_tests.SimpleDataPlane):

+    """

+    [L3 unicast route]

+      Do unicast route and output to specified port

+

+    Inject  eth 1/3 Tag2, SA000000112233, DA7072cf7cf3a3, SIP 192.168.1.100, DIP 192.168.2.2

+    Output  eth 1/1 Tag3, SA 000004223355, DA 000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=2/0xfff,eth_dst=70:72:cf:7c:f3:a3,eth_type=0x0800 goto:30

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x30001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20000003 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=3,group=0x30001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x20000003 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",eth_dst=70:72:cf:7c:f3:a3,eth_type=0x0800 goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x20000003 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=3,group=0x3000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x20000003 goto:60")

+

+        input_pkt = simple_packet(

+                '70 72 cf 7c f3 a3 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 06 b2 7b c0 a8 '

+                '01 0a c0 a8 02 02 00 03 00 06 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 2f 5d 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 03 '

+                '08 00 45 00 00 4e 04 d2 00 00 7e 06 b3 7b c0 a8 '

+                '01 0a c0 a8 02 02 00 03 00 06 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 2f 5d 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class l3ucast_route6(base_tests.SimpleDataPlane):

+    """

+    [L3 IPv6 unicast route]

+      Do unicast route and output to specified port

+

+    Inject  eth 1/3 Tag2, SA000000112233, DA7072cf7cf3a3, SIP 2014::2, DIP 2014::1

+    Output  eth 1/1 Tag2, SA 000004223355, DA 000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=2/0xfff,eth_dst=70:72:cf:7c:f3:a3,eth_type=0x86dd goto:30

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x86dd,ipv6_dst=2014::1/64 write:group=0x20000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",eth_dst=70:72:cf:7c:f3:a3,eth_type=0x86dd goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x20000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x86dd,ipv6_dst=2014::1/64 write:group=0x20000001 goto:60")

+

+        input_pkt = simple_packet(

+                '70 72 cf 7c f3 a3 00 00 00 11 22 33 81 00 00 02 '

+                '86 dd 60 00 00 00 00 08 11 7f 20 14 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 20 14 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 00 0d 00 07 00 08 '

+                'bf 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '86 dd 60 00 00 00 00 08 11 7e 20 14 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 20 14 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 00 0d 00 07 00 08 '

+                'bf 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class l3mcast_route(base_tests.SimpleDataPlane):

+    """

+    [L3 multicast route]

+      Do multicast route and output to specified ports

+

+    Inject  eth 1/3 Tag2, SA000000112233, DA01005E404477, SIP 192.168.1.100, DIP 224.0.2.2

+    Output  eth 1/1 original

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 eth_dst=01:00:5e:40:44:77/ff:ff:ff:80:00:00,eth_type=0x0800 goto:40

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=all,group=0x60020001 group=any,port=any,weight=0 group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=40,cmd=add,prio=401 eth_type=0x0800,ip_src=192.168.2.2,ip_dst=224.0.2.2,vlan_vid=2 write:group=0x60020001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 eth_dst=01:00:5e:40:44:77/ff:ff:ff:80:00:00,eth_type=0x0800 goto:40")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=all,group=0x60020001 group=any,port=any,weight=0 group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=40,cmd=add,prio=401 eth_type=0x0800,ip_src=192.168.2.2,ip_dst=224.0.2.2,vlan_vid=2 write:group=0x60020001 goto:60")

+

+        input_pkt = simple_packet(

+                '01 00 5e 40 44 77 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 84 91 ad c0 a8 '

+                '02 02 e0 00 02 02 00 17 00 08 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 0e 79 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '01 00 5e 40 44 77 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 84 91 ad c0 a8 '

+                '02 02 e0 00 02 02 00 17 00 08 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 0e 79 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class l3mcast_route6(base_tests.SimpleDataPlane):

+    """

+    [L3 IPv6 multicast route]

+      Do multicast route and output to specified ports

+

+    Inject  eth 1/5 Tag2, SA000000112233, DA333300224477, SIP 2014::2, DIP ff01::2

+    Output  eth 1/1 Tag2, original

+    Output  eth 1/3 Tag3, original

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=5,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 eth_dst=33:33:00:22:44:77/ff:ff:00:00:00:00,eth_type=0x86dd goto:40

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x30003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x50000003 group=any,port=any,weight=0 set_field=eth_src=00:00:05:22:33:99,set_field=vlan_vid=3,group=0x30003

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=all,group=0x60020001 group=any,port=any,weight=0 group=0x20001 group=any,port=any,weight=0 group=0x50000003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=40,cmd=add,prio=501 eth_type=0x86dd,ipv6_dst=ff01::2,vlan_vid=2 write:group=0x60020001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 eth_dst=33:33:00:22:44:77/ff:ff:00:00:00:00,eth_type=0x86dd goto:40")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(output_port2)+" group=any,port=any,weight=0 output="+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x50000003 group=any,port=any,weight=0 set_field=eth_src=00:00:05:22:33:99,set_field=vlan_vid=3,group=0x3000"+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=all,group=0x60020001 group=any,port=any,weight=0 group=0x2000"+str(output_port)+" group=any,port=any,weight=0 group=0x50000003")

+        apply_dpctl_mod(self, config, "flow-mod table=40,cmd=add,prio=401 eth_type=0x86dd,ipv6_dst=ff01::2,vlan_vid=2 write:group=0x60020001 goto:60")

+

+        input_pkt = simple_packet(

+                '33 33 00 22 44 77 00 00 00 11 22 33 81 00 00 02 '

+                '86 dd 60 00 00 00 00 26 3b 7f 20 14 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 ff 01 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '33 33 00 22 44 77 00 00 00 11 22 33 81 00 00 02 '

+                '86 dd 60 00 00 00 00 26 3b 7f 20 14 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 ff 01 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt2 = simple_packet(

+                '33 33 00 22 44 77 00 00 05 22 33 99 81 00 00 03 '

+                '86 dd 60 00 00 00 00 26 3b 7e 20 14 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 ff 01 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        verify_packet(self, str(output_pkt2), output_port2)

+

+

+class bridge_ucast(base_tests.SimpleDataPlane):

+    """

+    [Bridge unicast]

+      Do unicast bridge

+

+    Inject  eth 1/1 Tag2, SA000000112233, DA000000224477, SIP 192.168.2.1, DIP 192.168.2.2

+    Output  eth 1/3 untag

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 pop_vlan,output=3

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=501 vlan_vid=2,eth_dst=00:00:00:22:44:77 write:group=0x20003 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 pop_vlan,output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=50,cmd=add,prio=501 vlan_vid=2,eth_dst=00:00:00:22:44:77 write:group=0x2000"+str(output_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 22 44 77 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 '

+                '02 01 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 22 44 77 00 00 00 11 22 33 08 00 45 00 '

+                '00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 02 01 c0 a8 '

+                '02 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class bridge_mcast(base_tests.SimpleDataPlane):

+    """

+    [Bridge multicast]

+      Do multicast bridge

+

+    Inject  eth 1/5 Tag2, SA000000112233, DA110000224477, SIP 192.168.2.1, DIP 192.168.2.2

+    Output  eth 1/1 Tag2, SA000000112233, DA110000224477, SIP 192.168.2.1, DIP 192.168.2.2

+    Output  eth 1/3 untag

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=5,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 pop_vlan,output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=all,group=0x30020001 group=any,port=any,weight=0 group=0x20001 group=any,port=any,weight=0 group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=601 vlan_vid=2,eth_dst=11:00:00:22:44:77 write:group=0x30020001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port2)+" group=any,port=any,weight=0 pop_vlan,output="+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=all,group=0x30020001 group=any,port=any,weight=0 group=0x2000"+str(output_port)+" group=any,port=any,weight=0 group=0x2000"+str(output_port2))

+        apply_dpctl_mod(self, config, "flow-mod table=50,cmd=add,prio=501 vlan_vid=2,eth_dst=11:00:00:22:44:77 write:group=0x30020001 goto:60")

+

+        input_pkt = simple_packet(

+                '11 00 00 22 44 77 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 '

+                '02 01 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '11 00 00 22 44 77 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 '

+                '02 01 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt2 = simple_packet(

+                '11 00 00 22 44 77 00 00 00 11 22 33 08 00 45 00 '

+                '00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 02 01 c0 a8 '

+                '02 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        verify_packet(self, str(output_pkt2), output_port2)

+

+

+class bridge_dlf(base_tests.SimpleDataPlane):

+    """

+    [Bridge DLF]

+      Do DLF bridge

+

+    Inject  eth 1/5 Tag2, SA000000112233, DA110000224466, SIP 192.168.2.1, DIP 192.168.2.2

+    Output  eth 1/1 Tag2, SA000000112233, DA110000224477, SIP 192.168.2.1, DIP 192.168.2.2

+    Output  eth 1/3 untag

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=5,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 pop_vlan,output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=all,group=0x40020001 group=any,port=any,weight=0 group=0x20001 group=any,port=any,weight=0 group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=601 vlan_vid=2 write:group=0x40020001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port2)+" group=any,port=any,weight=0 pop_vlan,output="+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=all,group=0x40020001 group=any,port=any,weight=0 group=0x2000"+str(output_port)+" group=any,port=any,weight=0 group=0x2000"+str(output_port2))

+        apply_dpctl_mod(self, config, "flow-mod table=50,cmd=add,prio=601 vlan_vid=2 write:group=0x40020001 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 22 44 66 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 '

+                '02 01 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 22 44 66 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 '

+                '02 01 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt2 = simple_packet(

+                '00 00 00 22 44 66 00 00 00 11 22 33 08 00 45 00 '

+                '00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 02 01 c0 a8 '

+                '02 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        verify_packet(self, str(output_pkt2), output_port2)

+

diff --git a/Fabric/Utilities/acctonUseDpctl/pim_bidr.py b/Fabric/Utilities/acctonUseDpctl/pim_bidr.py
new file mode 100755
index 0000000..7d06450
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/pim_bidr.py
@@ -0,0 +1,183 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+

+

+class test_v4(base_tests.SimpleDataPlane):

+    """

+    [PIM BIDR IPv4]

+      PIM BIDR IPv4

+

+    Inject  eth 1/3 tag 3, SA unknown, DA 01005E010101, SIP 192.168.2.1, DIP 224.0.0.1

+    Output  eth 1/1 tag 2, SA 000001223355, DA 01005e010101, SIP 192.168.2.1, DIP 224.0.0.1

+

+    Inject  eth 1/1 tag 2, SA unknown, DA 01005E010101, SIP 192.168.2.1, DIP 224.0.0.1

+    Output  eth 1/3 tag 3, SA 000002223355, DA 01005e010101, SIP 192.168.2.1, DIP 224.0.0.1

+

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x00001fff goto:20

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x00001fff goto:20

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=20,cmd=add,prio=201 eth_dst=01:00:5e:01:01:01/ff:ff:ff:80:00:00,eth_type=0x0800 goto:40

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x30003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x58000001 group=any,port=any,weight=0 set_field=eth_src=00:00:01:22:33:55,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x58000002 group=any,port=any,weight=0 set_field=eth_src=00:00:02:22:33:55,set_field=vlan_vid=3,group=0x30003

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=all,group=0x60058001 group=any,port=any,weight=0 group=0x58000001 group=any,port=any,weight=0 group=0x58000002

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=40,cmd=add,prio=401 eth_type=0x800,ip_dst=224.0.0.1 write:group=0x60058001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(output_port)+",vlan_vid=0x1002/0x00001fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x00001fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 eth_dst=01:00:5e:01:01:01/ff:ff:ff:80:00:00,eth_type=0x0800 goto:40")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(input_port)+" group=any,port=any,weight=0 output="+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x58000001 group=any,port=any,weight=0 set_field=eth_src=00:00:01:22:33:55,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x58000002 group=any,port=any,weight=0 set_field=eth_src=00:00:02:22:33:55,set_field=vlan_vid=3,group=0x3000"+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=all,group=0x60058001 group=any,port=any,weight=0 group=0x58000001 group=any,port=any,weight=0 group=0x58000002")

+        apply_dpctl_mod(self, config, "flow-mod table=40,cmd=add,prio=401 eth_type=0x800,ip_dst=224.0.0.1 write:group=0x60058001 goto:60")

+

+        input_pkt = simple_packet(

+                '01 00 5e 01 01 01 00 00 00 00 00 aa 81 00 00 03 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 94 33 c0 a8 '

+                '02 01 e0 00 00 01 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '01 00 5e 01 01 01 00 00 01 22 33 55 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7e 00 95 33 c0 a8 '

+                '02 01 e0 00 00 01 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+        input_pkt = simple_packet(

+                '01 00 5e 01 01 01 00 00 00 00 00 aa 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 94 33 c0 a8 '

+                '02 01 e0 00 00 01 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '01 00 5e 01 01 01 00 00 02 22 33 55 81 00 00 03 '

+                '08 00 45 00 00 4e 04 d2 00 00 7e 00 95 33 c0 a8 '

+                '02 01 e0 00 00 01 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(output_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), input_port)

+

+

+class test_v6(base_tests.SimpleDataPlane):

+    """

+    [PIM BIDR IPv4]

+      PIM BIDR IPv4

+

+    Inject  eth 1/3 tag 3, SA unknown, DA 333300224477, SIP 2015::1, DIP ff01::2, UDP proto

+    Output  eth 1/1 tag 2, SA 000001223355, DA 333300224477, SIP 2015::1, DIP ff01::2

+

+    Inject  eth 1/1 tag 2, SA unknown, DA 333300224477, SIP 2015::1, DIP ff01::2, UDP proto

+    Output  eth 1/3 tag 3, SA 000002223355, DA 333300224477, SIP 2015::1, DIP ff01::2

+

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff goto:20

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=20,cmd=add,prio=201 eth_dst=33:33:00:22:44:77/ff:ff:00:00:00:00,eth_type=0x86dd goto:40

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x30003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x58000001 group=any,port=any,weight=0 set_field=eth_src=00:00:01:22:33:55,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x58000002 group=any,port=any,weight=0 set_field=eth_src=00:00:02:22:33:55,set_field=vlan_vid=3,group=0x30003

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=all,group=0x60058001 group=any,port=any,weight=0 group=0x58000001 group=any,port=any,weight=0 group=0x58000002

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=40,cmd=add,prio=401 eth_type=0x86dd,ipv6_dst=ff01::2 write:group=0x60058001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(output_port)+",vlan_vid=0x1002/0x00001fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x00001fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 eth_dst=33:33:00:22:44:77/ff:ff:00:00:00:00,eth_type=0x86dd goto:40")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(input_port)+" group=any,port=any,weight=0 output="+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x58000001 group=any,port=any,weight=0 set_field=eth_src=00:00:01:22:33:55,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x58000002 group=any,port=any,weight=0 set_field=eth_src=00:00:02:22:33:55,set_field=vlan_vid=3,group=0x3000"+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=all,group=0x60058001 group=any,port=any,weight=0 group=0x58000001 group=any,port=any,weight=0 group=0x58000002")

+        apply_dpctl_mod(self, config, "flow-mod table=40,cmd=add,prio=401 eth_type=0x86dd,ipv6_dst=ff01::2 write:group=0x60058001 goto:60")

+

+        input_pkt = simple_packet(

+                '33 33 00 22 44 77 00 00 00 00 00 aa 81 00 00 03 '

+                '86 dd 60 00 00 00 00 26 11 7f 20 15 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 ff 01 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 00 3f 00 41 00 26 '

+                '71 8f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d '

+                '0e 0f 10 11 12 13 14 15 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '33 33 00 22 44 77 00 00 01 22 33 55 81 00 00 02 '

+                '86 dd 60 00 00 00 00 26 11 7e 20 15 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 ff 01 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 00 3f 00 41 00 26 '

+                '71 8f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d '

+                '0e 0f 10 11 12 13 14 15 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+        input_pkt = simple_packet(

+                '33 33 00 22 44 77 00 00 00 00 00 aa 81 00 00 02 '

+                '86 dd 60 00 00 00 00 26 11 7f 20 15 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 ff 01 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 00 3f 00 41 00 26 '

+                '71 8f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d '

+                '0e 0f 10 11 12 13 14 15 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '33 33 00 22 44 77 00 00 02 22 33 55 81 00 00 03 '

+                '86 dd 60 00 00 00 00 26 11 7e 20 15 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 ff 01 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 00 3f 00 41 00 26 '

+                '71 8f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d '

+                '0e 0f 10 11 12 13 14 15 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(output_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), input_port)

diff --git a/Fabric/Utilities/acctonUseDpctl/stats.py b/Fabric/Utilities/acctonUseDpctl/stats.py
new file mode 100755
index 0000000..287d80b
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/stats.py
@@ -0,0 +1,86 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+

+

+class table_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-table")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Table stats reply nothing")

+

+class port_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-port")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Ports stats reply nothing")

+

+class queue_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-queue")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Queue stats reply nothing")

+

+class flow_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-flow")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Flow stats reply nothing")

+

+class aggr_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-aggr")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["flow_cnt"], 0, "No flow exist")

+

+class group_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-group")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Group stats reply nothing")

+

+class group_desc_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-group-desc")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Group desc stats reply nothing")

+

+class meter_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-meter")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Meter stats reply nothing")

+

+class meter_config(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "meter-config")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Meter config reply nothing")

+

diff --git a/Fabric/Utilities/acctonUseDpctl/util.py b/Fabric/Utilities/acctonUseDpctl/util.py
new file mode 100755
index 0000000..3942f84
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/util.py
@@ -0,0 +1,61 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import subprocess

+import json

+import os

+from pprint import pprint

+import time

+

+test_tmp_file=os.getcwd()+os.sep+"dpctloutputtmp.tmp"

+

+

+def apply_dpctl(test, config, cmd):

+    switch_ip = config["switch_ip"]

+    if len(switch_ip) == 0:

+        assert(0)

+

+    #apply dpctl command     

+    #subprocess.call(os.getcwd()+"/dpctl tcp:"+switch_ip+":6633 "+cmd+" > "+test_tmp_file, shell=True)

+    subprocess.call("dpctl tcp:"+switch_ip+":6633 "+cmd+" > "+test_tmp_file, shell=True)

+    time.sleep(0.2)

+    

+def apply_dpctl_get_cmd(test, config, cmd):

+

+    #create the tmp file

+    if not os.path.isfile(test_tmp_file):

+        open(test_tmp_file, "w").close()

+        subprocess.call(["sudo", "chmod", "a+w", test_tmp_file])

+

+    apply_dpctl(test, config, cmd)

+

+    #parse result

+    with open(test_tmp_file) as tmp_file:

+        try:

+            json_result=json.loads(tmp_file.read(), encoding='utf-8')

+        except ValueError:

+            subprocess.call("cat "+ test_tmp_file, shell=True)

+            """

+            https://docs.python.org/2/library/unittest.html#

+            """            

+            test.assertTrue(False, "NO json format, dpctl may fail")

+    

+    return json_result            

+    

+def apply_dpctl_mod(test, config, cmd):    

+    apply_dpctl(test, config, cmd)

+    

+    
\ No newline at end of file
diff --git a/Fabric/Utilities/acctonUseDpctl/vlan_translate.py b/Fabric/Utilities/acctonUseDpctl/vlan_translate.py
new file mode 100755
index 0000000..653bbad
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/vlan_translate.py
@@ -0,0 +1,224 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+

+

+class single_tag_to_double_tag(base_tests.SimpleDataPlane):

+    """																					 

+	[Single tag to double tag]																				

+		Add a specified outer tag to incoming tagged packet																			

+																					

+	Inject	eth 1/3	Tag 3, SA000000112233, DA000000113355, V4																		

+	Output	eth 1/1	Outter Tag 5, inner Tag 3, others not change																		

+																					

+	dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff apply:push_vlan=0x8100,set_field=vlan_vid=5 goto:20																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=3/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x50001 group=any,port=any,weight=0 output=1																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port=3 write:group=0x50001																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x30003 group=any,port=any,weight=0 pop_vlan,output=3																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=501 vlan_vid=3,eth_dst=00:00:00:11:22:33 write:group=0x30003 goto:60																				

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+		

+        test_ports = sorted(config["port_map"].keys())	

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x1fff apply:push_vlan=0x8100,set_field=vlan_vid=5 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=3/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x5000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port="+str(input_port)+" write:group=0x5000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(input_port)+" group=any,port=any,weight=0 pop_vlan,output="+str(input_port))

+        apply_dpctl_mod(self, config, " flow-mod table=50,cmd=add,prio=501 vlan_vid=3,eth_dst=00:00:00:11:22:33 write:group=0x3000"+str(input_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 05 '

+                '81 00 00 03 08 00 45 00 00 2e 04 d2 00 00 7f 00 '

+                'b2 47 c0 a8 01 64 c0 a8 02 02 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00')

+        

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        

+        

+        

+

+class double_tag_to_single_tag(base_tests.SimpleDataPlane):

+    """																					 

+	[Double tag to single tag]																				

+		Pop outter tag of incoming double tagged packet																			

+																					

+	Inject	eth 1/3	Outer 0x8100 + 6, Inner 0x8100 +3, SA000000112233, DA000000113355, V4																		

+	Output	eth 1/1	Tag 3, others not change																		

+																					

+	dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1006/0x1fff apply:pop_vlan,set_field=ofdpa_ovid:6 goto:11																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=11,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff,ofdpa_ovid=0x1006 goto:20																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=6/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x30001 group=any,port=any,weight=0 output=1																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port=3 write:group=0x30001																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x60003 group=any,port=any,weight=0 output=3																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=501 vlan_vid=6,eth_dst=00:00:00:11:22:33 write:group=0x60003 goto:60																				

+																				

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+		

+        test_ports = sorted(config["port_map"].keys())	

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1006/0x1fff apply:pop_vlan,set_field=ofdpa_ovid:6 goto:11")

+        apply_dpctl_mod(self, config, "flow-mod table=11,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x1fff,ofdpa_ovid=0x1006 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=6/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")        

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port="+str(input_port)+" write:group=0x3000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x6000"+str(input_port)+" group=any,port=any,weight=0 output="+str(input_port))

+        apply_dpctl_mod(self, config, "flow-mod table=50,cmd=add,prio=501 vlan_vid=6,eth_dst=00:00:00:11:22:33 write:group=0x6000"+str(input_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 06 '

+                '81 00 00 03 08 00 45 00 00 2a 04 d2 00 00 7f 00 '

+                'b2 4b c0 a8 01 64 c0 a8 02 02 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 2a 04 d2 00 00 7f 00 b2 4b c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00')

+        

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+                

+        

+

+

+class double2single_vlan_translate(base_tests.SimpleDataPlane):

+    """																					 

+	[Double tag to single tag and modify inner tag]																				

+		Pop outter tag of incoming double tagged packet and modify inner tag																			

+																					

+	Inject	eth 1/3	Outer 0x8100 + 6, Inner 0x8100 +3, SA000000112233, DA000000113355, V4																		

+	Output	eth 1/1	Tag 4, others not change																		

+																					

+	dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1006/0x1fff apply:pop_vlan,set_field=ofdpa_ovid:6 goto:11																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=11,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff,ofdpa_ovid=0x1006 apply:set_field=vlan_vid=4 goto:20																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=6/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x40001 group=any,port=any,weight=0 output=1																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port=3 write:group=0x40001																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x60003 group=any,port=any,weight=0 output=3																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=501 vlan_vid=6,eth_dst=00:00:00:11:22:33 write:group=0x60003 goto:60																				

+															

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+		

+        test_ports = sorted(config["port_map"].keys())	

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1006/0x1fff apply:pop_vlan,set_field=ofdpa_ovid:6 goto:11")

+        apply_dpctl_mod(self, config, "flow-mod table=11,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x1fff,ofdpa_ovid=0x1006 apply:set_field=vlan_vid=4 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=6/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")        

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x4000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port="+str(input_port)+" write:group=0x4000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x60003 group=any,port=any,weight=0 output="+str(input_port))

+        apply_dpctl_mod(self, config, "flow-mod table=50,cmd=add,prio=501 vlan_vid=6,eth_dst=00:00:00:11:22:33 write:group=0x6000"+str(input_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 06 '

+                '81 00 00 03 08 00 45 00 00 2a 04 d2 00 00 7f 00 '

+                'b2 4b c0 a8 01 64 c0 a8 02 02 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 04 '

+                '08 00 45 00 00 2a 04 d2 00 00 7f 00 b2 4b c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)   

+

+

+

+class vlan_translate(base_tests.SimpleDataPlane):

+    """																					 

+	[VLAN tanslate]																				

+		Swap incoming tagged packet to a specified VLAN tag																			

+																					

+	Inject	eth 1/3	Tag 3, SA000000112233, DA000000113355, V4																		

+	Output	eth 1/1	Tag 5, others not change																		

+																					

+	dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff apply:set_field=vlan_vid=5 goto:20																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=3/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x50001 group=any,port=any,weight=0 output=1																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port=3 write:group=0x50001																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x30003 group=any,port=any,weight=0 pop_vlan,output=3																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=501 vlan_vid=3,eth_dst=00:00:00:11:22:33 write:group=0x30003 goto:60																				

+																		

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+		

+        test_ports = sorted(config["port_map"].keys())	

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x1fff apply:set_field=vlan_vid=5 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=3/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x5000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port="+str(input_port)+" write:group=0x5000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(input_port)+" group=any,port=any,weight=0 pop_vlan,output="+str(input_port))

+        apply_dpctl_mod(self, config, "flow-mod table=50,cmd=add,prio=501 vlan_vid=3,eth_dst=00:00:00:11:22:33 write:group=0x3000"+str(input_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 05 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)        
\ No newline at end of file
diff --git a/Fabric/Utilities/acctonUseDpctl/wred.py b/Fabric/Utilities/acctonUseDpctl/wred.py
new file mode 100755
index 0000000..0d12caa
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/wred.py
@@ -0,0 +1,94 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+

+"""

+Not Verify yet, need to think how to verify meter

+"""

+

+class wred(base_tests.SimpleDataPlane):

+    """

+    [WRED]

+      WRED (DCTCP)

+

+    Inject  eth 1/1 untag, SA000000112233, DA000000000111, TCP ECN 01 [100%]

+    Output  eth 1/5 ECN 11

+

+    [CLI] interface eth 1/1 => switch priority default 1

+    dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20005 group=any,port=any,weight=0 output=5

+    dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1000/0xfff apply:set_field=vlan_vid=2 goto:20

+    dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1000/0xfff apply:set_field=vlan_vid=2 goto:20

+    dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 in_port=3 write:group=0x20005

+    dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port=1 write:group=0x20005

+    dpctl tcp:192.168.1.1:6633 queue-mod type=wred,port=5,queue=0 min=1,max=60,ecn=100,drop=100

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        input_port2 = test_ports[1]

+        output_port = test_ports[2]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1000/0xfff apply:set_field=vlan_vid=2 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port2)+",vlan_vid=0x1000/0xfff apply:set_field=vlan_vid=2 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 in_port="+str(input_port2)+" write:group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port="+str(input_port)+" write:group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28")

+        apply_dpctl_mod(self, config, "queue-mod type=wred,port="+str(output_port)+",queue=0 min=1,max=60,ecn=100,drop=100")

+

+        # TCP ecn = 01

+        input_pkt = simple_packet(

+                '70 72 cf 7c f3 a3 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 01 00 4e 04 d2 00 00 7f 06 b2 7b c0 a8 '

+                '01 0a c0 a8 02 02 00 03 00 06 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 2f 5d 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        # TCP ecn = 00

+        input_pkt2 = simple_packet(

+                '70 72 cf 7c f3 a3 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 06 b2 7b c0 a8 '

+                '01 0a c0 a8 02 02 00 03 00 06 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 2f 5d 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        # TCP ecn = 11

+        output_pkt = simple_packet(

+                '70 72 cf 7c f3 a3 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 11 00 4e 04 d2 00 00 7f 06 b2 7b c0 a8 '

+                '01 0a c0 a8 02 02 00 03 00 06 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 2f 5d 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        self.dataplane.send(input_port2, str(input_pkt2))

+        verify_packet(self, str(output_pkt), output_port)

+

diff --git a/Fabric/Utilities/platforms/bpp.py b/Fabric/Utilities/platforms/bpp.py
new file mode 100644
index 0000000..ba4e99a
--- /dev/null
+++ b/Fabric/Utilities/platforms/bpp.py
@@ -0,0 +1,89 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Platform configuration file
+platform == bpp
+"""
+
+###############################################################################
+#
+# This platform assumes BPP VPI specifications on the command line. 
+#
+###############################################################################
+
+import sys
+import os
+import argparse
+import subprocess
+import dppv
+
+# The port specification is passed via the "--platform-args" option to OFTest. 
+# Note that we must guard against abbreviations supported by argparse
+if not "--platform-args" in " ".join(sys.argv):
+    raise Exception("--platform-args must be specified")
+
+ap = argparse.ArgumentParser("bpp")
+ap.add_argument("--platform-args")
+(ops, rest) = ap.parse_known_args()
+
+if not "@" in ops.platform_args:
+    # Assume it is just a device name. Get the ports from the track database. 
+    if "," in ops.platform_args:
+        (type_, d) = ops.platform_args.split(",")
+    else:
+        (type_, d) = ("udp", ops.platform_args)
+
+    trackScript = "/usr/bin/track"
+    if not os.path.exists(trackScript):
+        raise Exception("Cannot find the track script (looked at %s" % trackScript)
+
+    ports = eval("[" + subprocess.check_output([trackScript, "getports", d]) + "]")
+    ops.platform_args = type_ + "," + ",".join( "%s@%s:%s" % (p, d, p) for p in ports)
+
+    print "new platform_args: ", ops.platform_args
+    exit;
+#
+###############################################################################
+
+vpi_port_map = {}
+ports = ops.platform_args.split(",")
+bpptype = "udp"
+if ports[0] == "udp" or ports[0] == "tcp":
+    bpptype = ports.pop(0)
+
+for ps in ports:
+    (p, vpi) = ps.split("@")
+    vpi_port_map[int(p)] = "bpp|%s|%s" % (bpptype, vpi)
+
+print vpi_port_map; 
+
+def platform_config_update(config):
+    """
+    Update configuration for the remote platform
+
+    @param config The configuration dictionary to use/update
+    This routine defines the port map used for this configuration
+    """
+
+    global vpi_port_map
+    config["port_map"] = vpi_port_map.copy()
+    config["caps_table_idx"] = 0
+    #
+    # The class for DataPlanePorts must be specified here:
+    #
+    config['dataplane'] = { 'portclass': dppv.DataPlanePortVPI }
+    config['allow_user'] = True
diff --git a/Fabric/Utilities/platforms/dppv.py b/Fabric/Utilities/platforms/dppv.py
new file mode 100644
index 0000000..da7de65
--- /dev/null
+++ b/Fabric/Utilities/platforms/dppv.py
@@ -0,0 +1,95 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+###############################################################################
+#
+# DataPlanePort implementation for VPI platforms. 
+#
+# The VPI-based platforms available here (bpp and vpi) depend upon
+# this module for the implementation of the OFTest DataPlanePort interface. 
+#
+###############################################################################
+import sys
+import os
+import logging
+import time
+
+from oftest import config
+
+# Requires the libvpi and pyvpi packages
+from vpi import vpi
+
+class DataPlanePortVPI:
+    """
+    Class defining a port monitoring VPI object.
+
+    """
+    
+    #
+    # OFTest creates and destroys DataPlanePorts for each test. 
+    # We just cache them here. 
+    cachedVPIs = {}
+    
+    def vpiInit(self, interface_name, port_number, pcap_dir="."):
+        self.vpiSpec = interface_name; 
+        if self.vpiSpec in self.cachedVPIs:
+            self.vpi = self.cachedVPIs[self.vpiSpec]
+        else:
+            self.vpi = vpi.Vpi(self.vpiSpec)
+            pcapspec = "pcapdump|%s/oft-port%.2d.pcap|mpls|PORT%d" % (pcap_dir, port_number, port_number)
+            self.vpi.AddSendRecvListener(pcapspec); 
+            self.cachedVPIs[self.vpiSpec] = self.vpi
+
+        return self.vpi
+
+    
+    def __init__(self, interface_name, port_number):
+        """
+        Set up a port monitor object
+        @param interface_name The name of the physical interface like eth1
+        @param port_number The port number associated with this port
+        """
+        self.interface_name = interface_name
+        self.port_number = port_number
+        logname = "VPI:" + interface_name
+        self.logger = logging.getLogger(logname)
+        
+        path = "."
+        if config['log_file']:
+            path = config['log_file']
+
+        if self.vpiInit(interface_name, port_number, 
+                        os.path.dirname(os.path.abspath(path))) == None:
+            raise Exception("Could not create VPI interface %s" % interface_name)
+
+        self.logger.info("VPI: %s:%d\n" % (interface_name, port_number))
+
+    def fileno(self):
+        return self.vpi.DescriptorGet()
+
+    def recv(self):
+        pkt = self.vpi.Recv(False) 
+        return (pkt, time.time())
+
+    def send(self, packet):
+        """
+        Send a packet to the dataplane port
+        @param packet The packet data to send to the port
+        @retval The number of bytes sent
+        """
+        _len = len(packet); 
+        self.vpi.Send(packet)
+        return _len; 
diff --git a/Fabric/Utilities/platforms/eth.py b/Fabric/Utilities/platforms/eth.py
new file mode 100644
index 0000000..056edce
--- /dev/null
+++ b/Fabric/Utilities/platforms/eth.py
@@ -0,0 +1,44 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Eth platform
+
+This platform uses the --interface command line option to choose the ethernet interfaces.
+"""
+
+def platform_config_update(config):
+    """
+    Update configuration for the local platform
+
+    @param config The configuration dictionary to use/update
+    """
+
+    port_map = {}
+
+    for (ofport, interface) in config["interfaces"]:
+        port_map[ofport] = interface
+
+    # Default to a veth configuration compatible with the reference switch
+    if not port_map:
+        port_map = {
+            1: 'veth1',
+            2: 'veth3',
+            3: 'veth5',
+            4: 'veth7',
+        }
+
+    config['port_map'] = port_map
diff --git a/Fabric/Utilities/platforms/local.py b/Fabric/Utilities/platforms/local.py
new file mode 100644
index 0000000..7caa1e5
--- /dev/null
+++ b/Fabric/Utilities/platforms/local.py
@@ -0,0 +1,38 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Local platform
+
+This platform uses veth pairs to send packets to and from a userspace
+switch. The switch should be connected to veth0, veth2, veth4, and veth6.
+"""
+
+def platform_config_update(config):
+    """
+    Update configuration for the local platform
+
+    @param config The configuration dictionary to use/update
+    """
+    base_of_port = 1
+    base_if_index = 1
+    port_count = 4
+
+    port_map = {}
+    # Use every other veth interface (veth1, veth3, ...)
+    for idx in range(port_count):
+        port_map[base_of_port + idx] = "veth%d" % (base_if_index + 2 * idx)
+    config['port_map'] = port_map
diff --git a/Fabric/Utilities/platforms/ovs-dummy.py b/Fabric/Utilities/platforms/ovs-dummy.py
new file mode 100644
index 0000000..1d81091
--- /dev/null
+++ b/Fabric/Utilities/platforms/ovs-dummy.py
@@ -0,0 +1,155 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Dummy platform
+
+This platform uses Open vSwitch dummy interfaces.
+"""
+
+import logging
+import os
+import select
+import socket
+import struct
+import sys
+import time
+from threading import Thread
+from threading import Lock
+
+RCV_TIMEOUT = 10000
+RUN_DIR = os.environ.get("OVS_RUNDIR", "/var/run/openvswitch")
+
+class DataPlanePortOVSDummy:
+    """
+    Class defining a port monitoring object that uses Unix domain
+    sockets for ports, intended for connecting to Open vSwitch "dummy"
+    netdevs.
+    """
+
+    def __init__(self, interface_name, port_number, max_pkts=1024):
+        """
+        Set up a port monitor object
+        @param interface_name The name of the physical interface like eth1
+        @param port_number The port number associated with this port
+        @param max_pkts Maximum number of pkts to keep in queue
+        """
+        self.interface_name = interface_name
+        self.max_pkts = max_pkts
+        self.port_number = port_number
+        self.txq = []
+        self.rxbuf = ""
+        logname = "dp-" + interface_name
+        self.logger = logging.getLogger(logname)
+        try:
+            self.socket = DataPlanePortOVSDummy.interface_open(interface_name)
+        except:
+            self.logger.info("Could not open socket")
+            raise
+        self.logger.info("Opened port monitor (class %s)", type(self).__name__)
+
+    @staticmethod
+    def interface_open(interface_name):
+        """
+        Open a Unix domain socket interface.
+        @param interface_name port name as a string such as 'eth1'
+        @retval s socket
+        """
+        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        s.settimeout(RCV_TIMEOUT)
+        s.setblocking(0)
+        s.connect("%s/%s" % (RUN_DIR, interface_name))
+        return s
+
+    def __del__(self):
+        if self.socket:
+            self.socket.close()
+
+    def fileno(self):
+        """
+        Return an integer file descriptor that can be passed to select(2).
+        """
+        return self.socket.fileno()
+
+    def recv(self):
+        while True:
+            rout, wout, eout = select.select([self.socket], [], [], 0)
+            if not rout:
+                return
+
+            if len(self.rxbuf) < 2:
+                n = 2 - len(self.rxbuf)
+            else:
+                frame_len = struct.unpack('>h', self.rxbuf[:2])[0]
+                n = (2 + frame_len) - len(self.rxbuf)
+
+            data = self.socket.recv(n)
+            self.rxbuf += data
+            if len(data) == n and len(self.rxbuf) > 2:
+                rcvtime = time.time()
+                packet = self.rxbuf[2:]
+                self.logger.debug("Pkt len " + str(len(packet)) +
+                         " in at " + str(rcvtime) + " on port " +
+                         str(self.port_number))
+                self.rxbuf = ""
+                return (packet, rcvtime)
+
+    def send(self, packet):
+        if len(self.txq) < self.max_pkts:
+            self.txq.append(struct.pack('>h', len(packet)) + packet)
+            retval = len(packet)
+        else:
+            retval = 0
+        self.__run_tx()
+        return retval
+
+    def __run_tx(self):
+        while self.txq:
+            rout, wout, eout = select.select([], [self.socket], [], 0)
+            if not wout:
+                return
+
+            retval = self.socket.send(self.txq[0])
+            if retval > 0:
+                self.txq[0] = self.txq[0][retval:]
+                if len(self.txq[0]) == 0:
+                    self.txq = self.txq[1:]
+        
+    def down(self):
+        pass
+
+    def up(self):
+        pass
+
+# Update this dictionary to suit your environment.
+dummy_port_map = {
+    1 : "p1",
+    2 : "p2",
+    3 : "p3",
+    4 : "p4"
+}
+
+def platform_config_update(config):
+    """
+    Update configuration for the dummy platform
+
+    @param config The configuration dictionary to use/update
+    """
+    global dummy_port_map
+    config["port_map"] = dummy_port_map.copy()
+    config["caps_table_idx"] = 0
+    config["dataplane"] = {"portclass": DataPlanePortOVSDummy}
+    config["allow_user"] = True
diff --git a/Fabric/Utilities/platforms/remote.py b/Fabric/Utilities/platforms/remote.py
new file mode 100644
index 0000000..95d1e25
--- /dev/null
+++ b/Fabric/Utilities/platforms/remote.py
@@ -0,0 +1,39 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Remote platform
+
+This platform uses physical ethernet interfaces.
+"""
+
+# Update this dictionary to suit your environment.
+remote_port_map = {
+    23 : "eth2",
+    24 : "eth3",
+    25 : "eth4",
+    26 : "eth5"
+}
+
+def platform_config_update(config):
+    """
+    Update configuration for the remote platform
+
+    @param config The configuration dictionary to use/update
+    """
+    global remote_port_map
+    config["port_map"] = remote_port_map.copy()
+    config["caps_table_idx"] = 0
diff --git a/Fabric/Utilities/platforms/veth8.py b/Fabric/Utilities/platforms/veth8.py
new file mode 100644
index 0000000..665e250
--- /dev/null
+++ b/Fabric/Utilities/platforms/veth8.py
@@ -0,0 +1,39 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+veth8 platform
+
+This platform uses 8 veth pairs. The switch should connect to veth0, veth2, ..., veth14.
+"""
+
+def platform_config_update(config):
+    """
+    Update configuration for the local platform
+
+    @param config The configuration dictionary to use/update
+    """
+
+    config['port_map'] = {
+        1: 'veth1',
+        2: 'veth3',
+        3: 'veth5',
+        4: 'veth7',
+        5: 'veth9',
+        6: 'veth11',
+        7: 'veth13',
+        8: 'veth15',
+    }
diff --git a/Fabric/Utilities/platforms/vpip.py b/Fabric/Utilities/platforms/vpip.py
new file mode 100644
index 0000000..5efea77
--- /dev/null
+++ b/Fabric/Utilities/platforms/vpip.py
@@ -0,0 +1,65 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Platform configuration file
+platform == vpi
+"""
+
+###############################################################################
+#
+# This platform module allows VPI port specifications on the command line. 
+#
+###############################################################################
+
+import sys
+import os
+import argparse
+import dppv
+
+# The port specification is passed via the "--platform-args" option to OFTest. 
+# Note that we must guard against abbreviations supported by argparse
+if not "--platform-args" in " ".join(sys.argv):
+    raise Exception("--platform-args must be specified")
+
+ap = argparse.ArgumentParser("vpi")
+ap.add_argument("--platform-args")
+(ops, rest) = ap.parse_known_args()
+
+vpi_port_map = {}
+ports = ops.platform_args.split(",")
+for ps in ports:
+    (p, vpi) = ps.split("@")
+    vpi_port_map[int(p)] = vpi
+
+print vpi_port_map; 
+
+def platform_config_update(config):
+    """
+    Update configuration for the remote platform
+
+    @param config The configuration dictionary to use/update
+    This routine defines the port map used for this configuration
+    """
+
+    global vpi_port_map
+    config["port_map"] = vpi_port_map.copy()
+    config["caps_table_idx"] = 0
+    #
+    # The class for DataPlanePorts must be specified here:
+    #
+    config['dataplane'] = { 'portclass': dppv.DataPlanePortVPI }
+    config['allow_user'] = True
diff --git a/Fabric/Utilities/src/python/.gitignore b/Fabric/Utilities/src/python/.gitignore
new file mode 100755
index 0000000..4b0053b
--- /dev/null
+++ b/Fabric/Utilities/src/python/.gitignore
@@ -0,0 +1,4 @@
+/build/
+/dist/
+/oftest.egg-info/
+*.pyc
diff --git a/Fabric/Utilities/src/python/loxi/LICENSE.pyloxi b/Fabric/Utilities/src/python/loxi/LICENSE.pyloxi
new file mode 100644
index 0000000..44ebddd
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/LICENSE.pyloxi
@@ -0,0 +1,36 @@
+OpenFlow Test Framework
+
+Copyright (c) 2010 The Board of Trustees of The Leland Stanford 
+Junior University
+
+Except where otherwise noted, this software is distributed under
+the OpenFlow Software License.  See 
+http://www.openflowswitch.org/wp/legal/ for current details.
+
+We are making the OpenFlow specification and associated documentation
+(Software) available for public use and benefit with the expectation
+that others will use, modify and enhance the Software and contribute
+those enhancements back to the community. However, since we would like
+to make the Software available for broadest use, with as few
+restrictions as possible permission is hereby granted, free of charge,
+to any person obtaining a copy of this Software to deal in the
+Software under the copyrights without restriction, including without
+limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions: 
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software. 
+
+THE SOFTWARE IS PROVIDED -Y´AS IS¡, WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+
+The name and trademarks of copyright holder(s) may NOT be used in
+advertising or publicity pertaining to the Software or any derivatives
+without specific, written prior permission. 
diff --git a/Fabric/Utilities/src/python/loxi/__init__.py b/Fabric/Utilities/src/python/loxi/__init__.py
new file mode 100644
index 0000000..088acb4
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/__init__.py
@@ -0,0 +1,85 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+# Automatically generated by LOXI from template toplevel_init.py
+# Do not modify
+
+version_names = {
+    1: "1.0",
+    2: "1.1",
+    3: "1.2",
+    4: "1.3",
+    5: "1.4",
+}
+
+def protocol(ver):
+    """
+    Import and return the protocol module for the given wire version.
+    """
+    if ver == 1:
+        import of10
+        return of10
+
+    if ver == 2:
+        import of11
+        return of11
+
+    if ver == 3:
+        import of12
+        return of12
+
+    if ver == 4:
+        import of13
+        return of13
+
+    if ver == 5:
+        import of14
+        return of14
+
+    raise ValueError
+
+class ProtocolError(Exception):
+    """
+    Raised when failing to deserialize an invalid OpenFlow message.
+    """
+    pass
+
+class Unimplemented(Exception):
+    """
+    Raised when an OpenFlow feature is not yet implemented in PyLoxi.
+    """
+    pass
+
+def unimplemented(msg):
+    raise Unimplemented(msg)
+
+class OFObject(object):
+    """
+    Superclass of all OpenFlow classes
+    """
+    def __init__(self, *args):
+        raise NotImplementedError("cannot instantiate abstract class")
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def show(self):
+        import loxi.pp
+        return loxi.pp.pp(self)
diff --git a/Fabric/Utilities/src/python/loxi/connection.py b/Fabric/Utilities/src/python/loxi/connection.py
new file mode 100644
index 0000000..2b1b5af
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/connection.py
@@ -0,0 +1,253 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright 2015, Big Switch Networks, Inc.
+
+"""
+OpenFlow connection class
+
+This class creates a thread which continually parses OpenFlow messages off the
+supplied socket and places them in a queue. The class has methods for reading messages
+from the RX queue, sending messages, and higher level operations like request-response
+and multipart transactions.
+"""
+
+import loxi
+import loxi.of14
+import logging
+import time
+import socket
+import errno
+import os
+import select
+from threading import Condition, Lock, Thread
+
+DEFAULT_TIMEOUT = 1
+
+class TransactionError(Exception):
+    def __str__(self):
+        return self.args[0]
+
+    @property
+    def msg(self):
+        return self.args[1]
+
+class Connection(Thread):
+    def __init__(self, sock):
+        Thread.__init__(self)
+        self.sock = sock
+        self.logger = logging.getLogger("connection")
+        self.rx = []
+        self.rx_cv = Condition()
+        self.tx_lock = Lock()
+        self.next_xid = 1
+        self.wakeup_rd, self.wakeup_wr = os.pipe()
+        self.finished = False
+        self.read_buffer = None
+
+    def run(self):
+        while not self.finished:
+            rd, wr, err = select.select([self.sock, self.wakeup_rd], [], [])
+            if self.sock in rd:
+                self.process_read()
+            if self.wakeup_rd in rd:
+                os.read(self.wakeup_rd, 1)
+        self.logger.debug("Exited event loop")
+
+    def process_read(self):
+        recvd = self.sock.recv(4096)
+
+        self.logger.debug("Received %d bytes", len(recvd))
+
+        buf = self.read_buffer
+        if buf:
+            buf += recvd
+        else:
+            buf = recvd
+
+        offset = 0
+        while offset < len(buf):
+            if offset + 8 > len(buf):
+                # Not enough data for the OpenFlow header
+                break
+
+            # Parse the header to get type
+            hdr_version, hdr_type, hdr_msglen, hdr_xid = loxi.of14.message.parse_header(buf[offset:])
+
+            # Use loxi to resolve ofp of matching version
+            ofp = loxi.protocol(hdr_version)
+
+            # Extract the raw message bytes
+            if (offset + hdr_msglen) > len(buf):
+                # Not enough data for the body
+                break
+            rawmsg = buf[offset : offset + hdr_msglen]
+            offset += hdr_msglen
+
+            msg = ofp.message.parse_message(rawmsg)
+            if not msg:
+                self.logger.warn("Could not parse message")
+                continue
+
+            self.logger.debug("Received message %s.%s xid %d length %d",
+                              type(msg).__module__, type(msg).__name__, hdr_xid, hdr_msglen)
+
+            with self.rx_cv:
+                self.rx.append(msg)
+                self.rx_cv.notify_all()
+
+        if offset == len(buf):
+            self.read_buffer = None
+        else:
+            self.read_buffer = buf[offset:]
+            self.logger.debug("%d bytes remaining", len(self.read_buffer))
+
+    def recv(self, predicate, timeout=DEFAULT_TIMEOUT):
+        """
+        Remove and return the first message in the RX queue for
+        which 'predicate' returns true
+        """
+        assert self.is_alive()
+
+        deadline = time.time() + timeout
+        while True:
+            with self.rx_cv:
+                for i, msg in enumerate(self.rx):
+                    if predicate(msg):
+                        return self.rx.pop(i)
+
+                now = time.time()
+                if now > deadline:
+                    return None
+                else:
+                    self.rx_cv.wait(deadline - now)
+
+    def recv_any(self, timeout=DEFAULT_TIMEOUT):
+        """
+        Return the first message in the RX queue
+        """
+        return self.recv(lambda msg: True, timeout)
+
+    def recv_xid(self, xid, timeout=DEFAULT_TIMEOUT):
+        """
+        Return the first message in the RX queue with XID 'xid'
+        """
+        return self.recv(lambda msg: msg.xid == xid, timeout)
+
+    def recv_class(self, klass, timeout=DEFAULT_TIMEOUT):
+        """
+        Return the first message in the RX queue which is an instance of 'klass'
+        """
+        return self.recv(lambda msg: isinstance(msg, klass), timeout)
+
+    def send_raw(self, buf):
+        """
+        Send raw bytes on the socket
+        """
+        assert self.is_alive()
+        self.logger.debug("Sending raw message length %d", len(buf))
+        with self.tx_lock:
+            if self.sock.sendall(buf) is not None:
+                raise RuntimeError("failed to send message to switch")
+
+    def send(self, msg):
+        """
+        Send a message
+        """
+        assert self.is_alive()
+
+        if msg.xid is None:
+            msg.xid = self._gen_xid()
+        buf = msg.pack()
+        self.logger.debug("Sending message %s.%s xid %d length %d",
+                          type(msg).__module__, type(msg).__name__, msg.xid, len(buf))
+        with self.tx_lock:
+            if self.sock.sendall(buf) is not None:
+                raise RuntimeError("failed to send message to switch")
+
+    def transact(self, msg, timeout=DEFAULT_TIMEOUT):
+        """
+        Send a message and return the reply
+        """
+        self.send(msg)
+        reply = self.recv_xid(msg.xid, timeout)
+        if reply is None:
+            raise TransactionError("no reply for %s" % type(msg).__name__, None)
+        elif isinstance(reply, loxi.protocol(reply.version).message.error_msg):
+            raise TransactionError("received %s in response to %s" % (type(reply).__name__, type(msg).__name__), reply)
+        return reply
+
+    def transact_multipart_generator(self, msg, timeout=DEFAULT_TIMEOUT):
+        """
+        Send a multipart request and yield each entry from the replies
+        """
+        self.send(msg)
+        finished = False
+        while not finished:
+            reply = self.recv_xid(msg.xid, timeout)
+            if reply is None:
+                raise TransactionError("no reply for %s" % type(msg).__name__, None)
+            elif not isinstance(reply, loxi.protocol(reply.version).message.stats_reply):
+                raise TransactionError("received %s in response to %s" % (type(reply).__name__, type(msg).__name__), reply)
+            for entry in reply.entries:
+                yield entry
+            finished = reply.flags & loxi.protocol(reply.version).OFPSF_REPLY_MORE == 0
+
+    def transact_multipart(self, msg, timeout=DEFAULT_TIMEOUT):
+        """
+        Send a multipart request and return all entries from the replies
+        """
+        entries = []
+        for entry in self.transact_multipart_generator(msg, timeout):
+            entries.append(entry)
+        return entries
+
+    def stop(self):
+        """
+        Signal the thread to exit and wait for it
+        """
+        assert not self.finished
+        self.logger.debug("Stopping connection")
+        self.finished = True
+        os.write(self.wakeup_wr, "x")
+        self.join()
+        self.sock.close()
+        os.close(self.wakeup_rd)
+        os.close(self.wakeup_wr)
+        self.logger.debug("Stopped connection")
+
+    def _gen_xid(self):
+        xid = self.next_xid
+        self.next_xid += 1
+        return xid
+
+def connect(ip, port=6653, daemon=True, ofp=loxi.of14):
+    """
+    Actively connect to a switch
+    """
+    soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    soc.connect((ip, port))
+    soc.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)
+    cxn = Connection(soc)
+    cxn.daemon = daemon
+    cxn.logger.debug("Connected to %s:%d", ip, port)
+    cxn.start()
+
+    cxn.send(ofp.message.hello())
+    if not cxn.recv(lambda msg: msg.type == ofp.OFPT_HELLO):
+        raise Exception("Did not receive HELLO")
+
+    return cxn
diff --git a/Fabric/Utilities/src/python/loxi/generic_util.py b/Fabric/Utilities/src/python/loxi/generic_util.py
new file mode 100644
index 0000000..90aa672
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/generic_util.py
@@ -0,0 +1,116 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+"""
+Utility functions independent of the protocol version
+"""
+
+# Automatically generated by LOXI from template generic_util.py
+# Do not modify
+
+import loxi
+import struct
+
+def pack_list(values):
+    return "".join([x.pack() for x in values])
+
+def unpack_list(reader, deserializer):
+    """
+    The deserializer function should take an OFReader and return the new object.
+    """
+    entries = []
+    while not reader.is_empty():
+        entries.append(deserializer(reader))
+    return entries
+
+def pad_to(alignment, length):
+    """
+    Return a string of zero bytes that will pad a string of length 'length' to
+    a multiple of 'alignment'.
+    """
+    return "\x00" * ((length + alignment - 1)/alignment*alignment - length)
+
+class OFReader(object):
+    """
+    Cursor over a read-only buffer
+
+    OpenFlow messages are best thought of as a sequence of elements of
+    variable size, rather than a C-style struct with fixed offsets and
+    known field lengths. This class supports efficiently reading
+    fields sequentially and is intended to be used recursively by the
+    parsers of child objects which will implicitly update the offset.
+
+    buf: buffer object
+    start: initial position in the buffer
+    length: number of bytes after start
+    offset: distance from start
+    """
+    def __init__(self, buf, start=0, length=None):
+        self.buf = buf
+        self.start = start
+        if length is None:
+            self.length = len(buf) - start
+        else:
+            self.length = length
+        self.offset = 0
+
+    def read(self, fmt):
+        st = struct.Struct(fmt)
+        if self.offset + st.size > self.length:
+            raise loxi.ProtocolError("Buffer too short")
+        result = st.unpack_from(self.buf, self.start+self.offset)
+        self.offset += st.size
+        return result
+
+    def read_all(self):
+        s = self.buf[(self.start+self.offset):(self.start+self.length)]
+        assert(len(s) == self.length - self.offset)
+        self.offset = self.length
+        return s
+
+    def peek(self, fmt, offset=0):
+        st = struct.Struct(fmt)
+        if self.offset + offset + st.size > self.length:
+            raise loxi.ProtocolError("Buffer too short")
+        result = st.unpack_from(self.buf, self.start + self.offset + offset)
+        return result
+
+    def skip(self, length):
+        if self.offset + length > self.length:
+            raise loxi.ProtocolError("Buffer too short")
+        self.offset += length
+
+    def skip_align(self):
+        new_offset = (self.offset + 7) / 8 * 8
+        if new_offset > self.length:
+            raise loxi.ProtocolError("Buffer too short")
+        self.offset = new_offset
+
+    def is_empty(self):
+        return self.offset == self.length
+
+    # Used when parsing objects that have their own length fields
+    def slice(self, length, rewind=0):
+        if self.offset + length - rewind > self.length:
+            raise loxi.ProtocolError("Buffer too short")
+        reader = OFReader(self.buf, self.start + self.offset - rewind, length)
+        reader.skip(rewind)
+        self.offset += length - rewind
+        return reader
diff --git a/Fabric/Utilities/src/python/loxi/of10/__init__.py b/Fabric/Utilities/src/python/loxi/of10/__init__.py
new file mode 100644
index 0000000..514c207
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of10/__init__.py
@@ -0,0 +1,31 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template init.py
+# Do not modify
+
+import const
+import action
+import message
+import common
+from const import *
+from common import *
+from loxi import ProtocolError
diff --git a/Fabric/Utilities/src/python/loxi/of10/action.py b/Fabric/Utilities/src/python/loxi/of10/action.py
new file mode 100644
index 0000000..c9f479b
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of10/action.py
@@ -0,0 +1,1091 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of10']
+
+class action(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = action.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = action()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("action {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(action):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_checksum(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_checksum_128(self.checksum))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_checksum()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_checksum {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_checksum
+
+class bsn_mirror(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, dest_port=None, vlan_tag=None, copy_stage=None):
+        if dest_port != None:
+            self.dest_port = dest_port
+        else:
+            self.dest_port = 0
+        if vlan_tag != None:
+            self.vlan_tag = vlan_tag
+        else:
+            self.vlan_tag = 0
+        if copy_stage != None:
+            self.copy_stage = copy_stage
+        else:
+            self.copy_stage = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dest_port))
+        packed.append(struct.pack("!L", self.vlan_tag))
+        packed.append(struct.pack("!B", self.copy_stage))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_mirror()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.dest_port = reader.read("!L")[0]
+        obj.vlan_tag = reader.read("!L")[0]
+        obj.copy_stage = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dest_port != other.dest_port: return False
+        if self.vlan_tag != other.vlan_tag: return False
+        if self.copy_stage != other.copy_stage: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_mirror {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dest_port = ");
+                q.text("%#x" % self.dest_port)
+                q.text(","); q.breakable()
+                q.text("vlan_tag = ");
+                q.text("%#x" % self.vlan_tag)
+                q.text(","); q.breakable()
+                q.text("copy_stage = ");
+                q.text("%#x" % self.copy_stage)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_mirror
+
+class bsn_set_tunnel_dst(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, dst=None):
+        if dst != None:
+            self.dst = dst
+        else:
+            self.dst = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dst))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_tunnel_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.dst = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dst != other.dst: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_tunnel_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dst = ");
+                q.text("%#x" % self.dst)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_set_tunnel_dst
+
+class enqueue(action):
+    type = 11
+
+    def __init__(self, port=None, queue_id=None):
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 6)
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = enqueue()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(6)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port != other.port: return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("enqueue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[11] = enqueue
+
+class nicira(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 8992
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = nicira.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!H")[0]
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira
+
+class nicira_dec_ttl(nicira):
+    type = 65535
+    experimenter = 8992
+    subtype = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_dec_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == 18)
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_dec_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+nicira.subtypes[18] = nicira_dec_ttl
+
+class output(action):
+    type = 0
+
+    def __init__(self, port=None, max_len=None):
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if max_len != None:
+            self.max_len = max_len
+        else:
+            self.max_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", self.max_len))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = output()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.port = util.unpack_port_no(reader)
+        obj.max_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port != other.port: return False
+        if self.max_len != other.max_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("max_len = ");
+                q.text("%#x" % self.max_len)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[0] = output
+
+class set_dl_dst(action):
+    type = 5
+
+    def __init__(self, dl_addr=None):
+        if dl_addr != None:
+            self.dl_addr = dl_addr
+        else:
+            self.dl_addr = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!6B", *self.dl_addr))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_dl_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.dl_addr = list(reader.read('!6B'))
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dl_addr != other.dl_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_dl_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dl_addr = ");
+                q.text(util.pretty_mac(self.dl_addr))
+            q.breakable()
+        q.text('}')
+
+action.subtypes[5] = set_dl_dst
+
+class set_dl_src(action):
+    type = 4
+
+    def __init__(self, dl_addr=None):
+        if dl_addr != None:
+            self.dl_addr = dl_addr
+        else:
+            self.dl_addr = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!6B", *self.dl_addr))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_dl_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.dl_addr = list(reader.read('!6B'))
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dl_addr != other.dl_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_dl_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dl_addr = ");
+                q.text(util.pretty_mac(self.dl_addr))
+            q.breakable()
+        q.text('}')
+
+action.subtypes[4] = set_dl_src
+
+class set_nw_dst(action):
+    type = 7
+
+    def __init__(self, nw_addr=None):
+        if nw_addr != None:
+            self.nw_addr = nw_addr
+        else:
+            self.nw_addr = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.nw_addr))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 7)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_addr = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_addr != other.nw_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_addr = ");
+                q.text("%#x" % self.nw_addr)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[7] = set_nw_dst
+
+class set_nw_src(action):
+    type = 6
+
+    def __init__(self, nw_addr=None):
+        if nw_addr != None:
+            self.nw_addr = nw_addr
+        else:
+            self.nw_addr = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.nw_addr))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_addr = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_addr != other.nw_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_addr = ");
+                q.text("%#x" % self.nw_addr)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[6] = set_nw_src
+
+class set_nw_tos(action):
+    type = 8
+
+    def __init__(self, nw_tos=None):
+        if nw_tos != None:
+            self.nw_tos = nw_tos
+        else:
+            self.nw_tos = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.nw_tos))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_tos()
+        _type = reader.read("!H")[0]
+        assert(_type == 8)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_tos = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_tos != other.nw_tos: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_tos {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_tos = ");
+                q.text("%#x" % self.nw_tos)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[8] = set_nw_tos
+
+class set_tp_dst(action):
+    type = 10
+
+    def __init__(self, tp_port=None):
+        if tp_port != None:
+            self.tp_port = tp_port
+        else:
+            self.tp_port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.tp_port))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_tp_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 10)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.tp_port = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.tp_port != other.tp_port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_tp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("tp_port = ");
+                q.text("%#x" % self.tp_port)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[10] = set_tp_dst
+
+class set_tp_src(action):
+    type = 9
+
+    def __init__(self, tp_port=None):
+        if tp_port != None:
+            self.tp_port = tp_port
+        else:
+            self.tp_port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.tp_port))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_tp_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 9)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.tp_port = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.tp_port != other.tp_port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_tp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("tp_port = ");
+                q.text("%#x" % self.tp_port)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[9] = set_tp_src
+
+class set_vlan_pcp(action):
+    type = 2
+
+    def __init__(self, vlan_pcp=None):
+        if vlan_pcp != None:
+            self.vlan_pcp = vlan_pcp
+        else:
+            self.vlan_pcp = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.vlan_pcp))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_vlan_pcp()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.vlan_pcp = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vlan_pcp != other.vlan_pcp: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_vlan_pcp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vlan_pcp = ");
+                q.text("%#x" % self.vlan_pcp)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[2] = set_vlan_pcp
+
+class set_vlan_vid(action):
+    type = 1
+
+    def __init__(self, vlan_vid=None):
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_vlan_vid()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.vlan_vid = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vlan_vid != other.vlan_vid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[1] = set_vlan_vid
+
+class strip_vlan(action):
+    type = 3
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = strip_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("strip_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[3] = strip_vlan
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of10/common.py b/Fabric/Utilities/src/python/loxi/of10/common.py
new file mode 100644
index 0000000..8d43657
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of10/common.py
@@ -0,0 +1,1315 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of10']
+
+class bsn_interface(loxi.OFObject):
+
+    def __init__(self, hw_addr=None, name=None, ipv4_addr=None, ipv4_netmask=None):
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if ipv4_addr != None:
+            self.ipv4_addr = ipv4_addr
+        else:
+            self.ipv4_addr = 0
+        if ipv4_netmask != None:
+            self.ipv4_netmask = ipv4_netmask
+        else:
+            self.ipv4_netmask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.ipv4_addr))
+        packed.append(struct.pack("!L", self.ipv4_netmask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_interface()
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.ipv4_addr = reader.read("!L")[0]
+        obj.ipv4_netmask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.ipv4_addr != other.ipv4_addr: return False
+        if self.ipv4_netmask != other.ipv4_netmask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_interface {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("ipv4_addr = ");
+                q.text(util.pretty_ipv4(self.ipv4_addr))
+                q.text(","); q.breakable()
+                q.text("ipv4_netmask = ");
+                q.text(util.pretty_ipv4(self.ipv4_netmask))
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bsn_vport.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_vport()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport_l2gre(bsn_vport):
+    type = 1
+
+    def __init__(self, flags=None, port_no=None, loopback_port_no=None, local_mac=None, nh_mac=None, src_ip=None, dst_ip=None, dscp=None, ttl=None, vpn=None, rate_limit=None, if_name=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if loopback_port_no != None:
+            self.loopback_port_no = loopback_port_no
+        else:
+            self.loopback_port_no = 0
+        if local_mac != None:
+            self.local_mac = local_mac
+        else:
+            self.local_mac = [0,0,0,0,0,0]
+        if nh_mac != None:
+            self.nh_mac = nh_mac
+        else:
+            self.nh_mac = [0,0,0,0,0,0]
+        if src_ip != None:
+            self.src_ip = src_ip
+        else:
+            self.src_ip = 0
+        if dst_ip != None:
+            self.dst_ip = dst_ip
+        else:
+            self.dst_ip = 0
+        if dscp != None:
+            self.dscp = dscp
+        else:
+            self.dscp = 0
+        if ttl != None:
+            self.ttl = ttl
+        else:
+            self.ttl = 0
+        if vpn != None:
+            self.vpn = vpn
+        else:
+            self.vpn = 0
+        if rate_limit != None:
+            self.rate_limit = rate_limit
+        else:
+            self.rate_limit = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.flags))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(util.pack_port_no(self.loopback_port_no))
+        packed.append(struct.pack("!6B", *self.local_mac))
+        packed.append(struct.pack("!6B", *self.nh_mac))
+        packed.append(struct.pack("!L", self.src_ip))
+        packed.append(struct.pack("!L", self.dst_ip))
+        packed.append(struct.pack("!B", self.dscp))
+        packed.append(struct.pack("!B", self.ttl))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.vpn))
+        packed.append(struct.pack("!L", self.rate_limit))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_l2gre()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.flags = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.loopback_port_no = util.unpack_port_no(reader)
+        obj.local_mac = list(reader.read('!6B'))
+        obj.nh_mac = list(reader.read('!6B'))
+        obj.src_ip = reader.read("!L")[0]
+        obj.dst_ip = reader.read("!L")[0]
+        obj.dscp = reader.read("!B")[0]
+        obj.ttl = reader.read("!B")[0]
+        reader.skip(2)
+        obj.vpn = reader.read("!L")[0]
+        obj.rate_limit = reader.read("!L")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.loopback_port_no != other.loopback_port_no: return False
+        if self.local_mac != other.local_mac: return False
+        if self.nh_mac != other.nh_mac: return False
+        if self.src_ip != other.src_ip: return False
+        if self.dst_ip != other.dst_ip: return False
+        if self.dscp != other.dscp: return False
+        if self.ttl != other.ttl: return False
+        if self.vpn != other.vpn: return False
+        if self.rate_limit != other.rate_limit: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_l2gre {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("loopback_port_no = ");
+                q.text(util.pretty_port(self.loopback_port_no))
+                q.text(","); q.breakable()
+                q.text("local_mac = ");
+                q.text(util.pretty_mac(self.local_mac))
+                q.text(","); q.breakable()
+                q.text("nh_mac = ");
+                q.text(util.pretty_mac(self.nh_mac))
+                q.text(","); q.breakable()
+                q.text("src_ip = ");
+                q.text(util.pretty_ipv4(self.src_ip))
+                q.text(","); q.breakable()
+                q.text("dst_ip = ");
+                q.text(util.pretty_ipv4(self.dst_ip))
+                q.text(","); q.breakable()
+                q.text("dscp = ");
+                q.text("%#x" % self.dscp)
+                q.text(","); q.breakable()
+                q.text("ttl = ");
+                q.text("%#x" % self.ttl)
+                q.text(","); q.breakable()
+                q.text("vpn = ");
+                q.text("%#x" % self.vpn)
+                q.text(","); q.breakable()
+                q.text("rate_limit = ");
+                q.text("%#x" % self.rate_limit)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[1] = bsn_vport_l2gre
+
+class bsn_vport_q_in_q(bsn_vport):
+    type = 0
+
+    def __init__(self, port_no=None, ingress_tpid=None, ingress_vlan_id=None, egress_tpid=None, egress_vlan_id=None, if_name=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if ingress_tpid != None:
+            self.ingress_tpid = ingress_tpid
+        else:
+            self.ingress_tpid = 0
+        if ingress_vlan_id != None:
+            self.ingress_vlan_id = ingress_vlan_id
+        else:
+            self.ingress_vlan_id = 0
+        if egress_tpid != None:
+            self.egress_tpid = egress_tpid
+        else:
+            self.egress_tpid = 0
+        if egress_vlan_id != None:
+            self.egress_vlan_id = egress_vlan_id
+        else:
+            self.egress_vlan_id = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.port_no))
+        packed.append(struct.pack("!H", self.ingress_tpid))
+        packed.append(struct.pack("!H", self.ingress_vlan_id))
+        packed.append(struct.pack("!H", self.egress_tpid))
+        packed.append(struct.pack("!H", self.egress_vlan_id))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_q_in_q()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.port_no = reader.read("!L")[0]
+        obj.ingress_tpid = reader.read("!H")[0]
+        obj.ingress_vlan_id = reader.read("!H")[0]
+        obj.egress_tpid = reader.read("!H")[0]
+        obj.egress_vlan_id = reader.read("!H")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.ingress_tpid != other.ingress_tpid: return False
+        if self.ingress_vlan_id != other.ingress_vlan_id: return False
+        if self.egress_tpid != other.egress_tpid: return False
+        if self.egress_vlan_id != other.egress_vlan_id: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_q_in_q {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text("%#x" % self.port_no)
+                q.text(","); q.breakable()
+                q.text("ingress_tpid = ");
+                q.text("%#x" % self.ingress_tpid)
+                q.text(","); q.breakable()
+                q.text("ingress_vlan_id = ");
+                q.text("%#x" % self.ingress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("egress_tpid = ");
+                q.text("%#x" % self.egress_tpid)
+                q.text(","); q.breakable()
+                q.text("egress_vlan_id = ");
+                q.text("%#x" % self.egress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[0] = bsn_vport_q_in_q
+
+class flow_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, match=None, duration_sec=None, duration_nsec=None, priority=None, idle_timeout=None, hard_timeout=None, cookie=None, packet_count=None, byte_count=None, actions=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append('\x00' * 6)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.match = ofp.match.unpack(reader)
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        reader.skip(6)
+        obj.cookie = reader.read("!Q")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.match != other.match: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.priority != other.priority: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.cookie != other.cookie: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+
+class match_v1(loxi.OFObject):
+
+    def __init__(self, wildcards=None, in_port=None, eth_src=None, eth_dst=None, vlan_vid=None, vlan_pcp=None, eth_type=None, ip_dscp=None, ip_proto=None, ipv4_src=None, ipv4_dst=None, tcp_src=None, tcp_dst=None):
+        if wildcards != None:
+            self.wildcards = wildcards
+        else:
+            self.wildcards = util.init_wc_bmap()
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if eth_src != None:
+            self.eth_src = eth_src
+        else:
+            self.eth_src = [0,0,0,0,0,0]
+        if eth_dst != None:
+            self.eth_dst = eth_dst
+        else:
+            self.eth_dst = [0,0,0,0,0,0]
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        if vlan_pcp != None:
+            self.vlan_pcp = vlan_pcp
+        else:
+            self.vlan_pcp = 0
+        if eth_type != None:
+            self.eth_type = eth_type
+        else:
+            self.eth_type = 0
+        if ip_dscp != None:
+            self.ip_dscp = ip_dscp
+        else:
+            self.ip_dscp = 0
+        if ip_proto != None:
+            self.ip_proto = ip_proto
+        else:
+            self.ip_proto = 0
+        if ipv4_src != None:
+            self.ipv4_src = ipv4_src
+        else:
+            self.ipv4_src = 0
+        if ipv4_dst != None:
+            self.ipv4_dst = ipv4_dst
+        else:
+            self.ipv4_dst = 0
+        if tcp_src != None:
+            self.tcp_src = tcp_src
+        else:
+            self.tcp_src = 0
+        if tcp_dst != None:
+            self.tcp_dst = tcp_dst
+        else:
+            self.tcp_dst = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_wc_bmap(self.wildcards))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(struct.pack("!6B", *self.eth_src))
+        packed.append(struct.pack("!6B", *self.eth_dst))
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append(struct.pack("!B", self.vlan_pcp))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.eth_type))
+        packed.append(struct.pack("!B", self.ip_dscp))
+        packed.append(struct.pack("!B", self.ip_proto))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.ipv4_src))
+        packed.append(struct.pack("!L", self.ipv4_dst))
+        packed.append(struct.pack("!H", self.tcp_src))
+        packed.append(struct.pack("!H", self.tcp_dst))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = match_v1()
+        obj.wildcards = util.unpack_wc_bmap(reader)
+        obj.in_port = util.unpack_port_no(reader)
+        obj.eth_src = list(reader.read('!6B'))
+        obj.eth_dst = list(reader.read('!6B'))
+        obj.vlan_vid = reader.read("!H")[0]
+        obj.vlan_pcp = reader.read("!B")[0]
+        reader.skip(1)
+        obj.eth_type = reader.read("!H")[0]
+        obj.ip_dscp = reader.read("!B")[0]
+        obj.ip_proto = reader.read("!B")[0]
+        reader.skip(2)
+        obj.ipv4_src = reader.read("!L")[0]
+        obj.ipv4_dst = reader.read("!L")[0]
+        obj.tcp_src = reader.read("!H")[0]
+        obj.tcp_dst = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.wildcards != other.wildcards: return False
+        if self.in_port != other.in_port: return False
+        if self.eth_src != other.eth_src: return False
+        if self.eth_dst != other.eth_dst: return False
+        if self.vlan_vid != other.vlan_vid: return False
+        if self.vlan_pcp != other.vlan_pcp: return False
+        if self.eth_type != other.eth_type: return False
+        if self.ip_dscp != other.ip_dscp: return False
+        if self.ip_proto != other.ip_proto: return False
+        if self.ipv4_src != other.ipv4_src: return False
+        if self.ipv4_dst != other.ipv4_dst: return False
+        if self.tcp_src != other.tcp_src: return False
+        if self.tcp_dst != other.tcp_dst: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("match_v1 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("wildcards = ");
+                q.text(util.pretty_wildcards(self.wildcards))
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("eth_src = ");
+                q.text(util.pretty_mac(self.eth_src))
+                q.text(","); q.breakable()
+                q.text("eth_dst = ");
+                q.text(util.pretty_mac(self.eth_dst))
+                q.text(","); q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+                q.text(","); q.breakable()
+                q.text("vlan_pcp = ");
+                q.text("%#x" % self.vlan_pcp)
+                q.text(","); q.breakable()
+                q.text("eth_type = ");
+                q.text("%#x" % self.eth_type)
+                q.text(","); q.breakable()
+                q.text("ip_dscp = ");
+                q.text("%#x" % self.ip_dscp)
+                q.text(","); q.breakable()
+                q.text("ip_proto = ");
+                q.text("%#x" % self.ip_proto)
+                q.text(","); q.breakable()
+                q.text("ipv4_src = ");
+                q.text(util.pretty_ipv4(self.ipv4_src))
+                q.text(","); q.breakable()
+                q.text("ipv4_dst = ");
+                q.text(util.pretty_ipv4(self.ipv4_dst))
+                q.text(","); q.breakable()
+                q.text("tcp_src = ");
+                q.text("%#x" % self.tcp_src)
+                q.text(","); q.breakable()
+                q.text("tcp_dst = ");
+                q.text("%#x" % self.tcp_dst)
+            q.breakable()
+        q.text('}')
+
+
+class packet_queue(loxi.OFObject):
+
+    def __init__(self, queue_id=None, properties=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 2)
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_queue()
+        obj.queue_id = reader.read("!L")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 6)
+        reader.skip(2)
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.common.queue_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class port_desc(loxi.OFObject):
+
+    def __init__(self, port_no=None, hw_addr=None, name=None, config=None, state=None, curr=None, advertised=None, supported=None, peer=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if state != None:
+            self.state = state
+        else:
+            self.state = 0
+        if curr != None:
+            self.curr = curr
+        else:
+            self.curr = 0
+        if advertised != None:
+            self.advertised = advertised
+        else:
+            self.advertised = 0
+        if supported != None:
+            self.supported = supported
+        else:
+            self.supported = 0
+        if peer != None:
+            self.peer = peer
+        else:
+            self.peer = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.state))
+        packed.append(struct.pack("!L", self.curr))
+        packed.append(struct.pack("!L", self.advertised))
+        packed.append(struct.pack("!L", self.supported))
+        packed.append(struct.pack("!L", self.peer))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc()
+        obj.port_no = util.unpack_port_no(reader)
+        obj.hw_addr = list(reader.read('!6B'))
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.config = reader.read("!L")[0]
+        obj.state = reader.read("!L")[0]
+        obj.curr = reader.read("!L")[0]
+        obj.advertised = reader.read("!L")[0]
+        obj.supported = reader.read("!L")[0]
+        obj.peer = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.config != other.config: return False
+        if self.state != other.state: return False
+        if self.curr != other.curr: return False
+        if self.advertised != other.advertised: return False
+        if self.supported != other.supported: return False
+        if self.peer != other.peer: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("state = ");
+                q.text("%#x" % self.state)
+                q.text(","); q.breakable()
+                q.text("curr = ");
+                q.text("%#x" % self.curr)
+                q.text(","); q.breakable()
+                q.text("advertised = ");
+                q.text("%#x" % self.advertised)
+                q.text(","); q.breakable()
+                q.text("supported = ");
+                q.text("%#x" % self.supported)
+                q.text(","); q.breakable()
+                q.text("peer = ");
+                q.text("%#x" % self.peer)
+            q.breakable()
+        q.text('}')
+
+
+class port_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, rx_packets=None, tx_packets=None, rx_bytes=None, tx_bytes=None, rx_dropped=None, tx_dropped=None, rx_errors=None, tx_errors=None, rx_frame_err=None, rx_over_err=None, rx_crc_err=None, collisions=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if rx_packets != None:
+            self.rx_packets = rx_packets
+        else:
+            self.rx_packets = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if rx_bytes != None:
+            self.rx_bytes = rx_bytes
+        else:
+            self.rx_bytes = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if rx_dropped != None:
+            self.rx_dropped = rx_dropped
+        else:
+            self.rx_dropped = 0
+        if tx_dropped != None:
+            self.tx_dropped = tx_dropped
+        else:
+            self.tx_dropped = 0
+        if rx_errors != None:
+            self.rx_errors = rx_errors
+        else:
+            self.rx_errors = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        if rx_frame_err != None:
+            self.rx_frame_err = rx_frame_err
+        else:
+            self.rx_frame_err = 0
+        if rx_over_err != None:
+            self.rx_over_err = rx_over_err
+        else:
+            self.rx_over_err = 0
+        if rx_crc_err != None:
+            self.rx_crc_err = rx_crc_err
+        else:
+            self.rx_crc_err = 0
+        if collisions != None:
+            self.collisions = collisions
+        else:
+            self.collisions = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 6)
+        packed.append(struct.pack("!Q", self.rx_packets))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.rx_bytes))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.rx_dropped))
+        packed.append(struct.pack("!Q", self.tx_dropped))
+        packed.append(struct.pack("!Q", self.rx_errors))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        packed.append(struct.pack("!Q", self.rx_frame_err))
+        packed.append(struct.pack("!Q", self.rx_over_err))
+        packed.append(struct.pack("!Q", self.rx_crc_err))
+        packed.append(struct.pack("!Q", self.collisions))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(6)
+        obj.rx_packets = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.rx_bytes = reader.read("!Q")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.rx_dropped = reader.read("!Q")[0]
+        obj.tx_dropped = reader.read("!Q")[0]
+        obj.rx_errors = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        obj.rx_frame_err = reader.read("!Q")[0]
+        obj.rx_over_err = reader.read("!Q")[0]
+        obj.rx_crc_err = reader.read("!Q")[0]
+        obj.collisions = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.rx_packets != other.rx_packets: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.rx_bytes != other.rx_bytes: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.rx_dropped != other.rx_dropped: return False
+        if self.tx_dropped != other.tx_dropped: return False
+        if self.rx_errors != other.rx_errors: return False
+        if self.tx_errors != other.tx_errors: return False
+        if self.rx_frame_err != other.rx_frame_err: return False
+        if self.rx_over_err != other.rx_over_err: return False
+        if self.rx_crc_err != other.rx_crc_err: return False
+        if self.collisions != other.collisions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("rx_packets = ");
+                q.text("%#x" % self.rx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("rx_bytes = ");
+                q.text("%#x" % self.rx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("rx_dropped = ");
+                q.text("%#x" % self.rx_dropped)
+                q.text(","); q.breakable()
+                q.text("tx_dropped = ");
+                q.text("%#x" % self.tx_dropped)
+                q.text(","); q.breakable()
+                q.text("rx_errors = ");
+                q.text("%#x" % self.rx_errors)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+                q.text(","); q.breakable()
+                q.text("rx_frame_err = ");
+                q.text("%#x" % self.rx_frame_err)
+                q.text(","); q.breakable()
+                q.text("rx_over_err = ");
+                q.text("%#x" % self.rx_over_err)
+                q.text(","); q.breakable()
+                q.text("rx_crc_err = ");
+                q.text("%#x" % self.rx_crc_err)
+                q.text(","); q.breakable()
+                q.text("collisions = ");
+                q.text("%#x" % self.collisions)
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = queue_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop_min_rate(queue_prop):
+    type = 1
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_min_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_min_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[1] = queue_prop_min_rate
+
+class queue_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, queue_id=None, tx_bytes=None, tx_packets=None, tx_errors=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(2)
+        obj.queue_id = reader.read("!L")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.tx_errors != other.tx_errors: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+            q.breakable()
+        q.text('}')
+
+
+class table_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, name=None, wildcards=None, max_entries=None, active_count=None, lookup_count=None, matched_count=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if wildcards != None:
+            self.wildcards = wildcards
+        else:
+            self.wildcards = util.init_wc_bmap()
+        if max_entries != None:
+            self.max_entries = max_entries
+        else:
+            self.max_entries = 0
+        if active_count != None:
+            self.active_count = active_count
+        else:
+            self.active_count = 0
+        if lookup_count != None:
+            self.lookup_count = lookup_count
+        else:
+            self.lookup_count = 0
+        if matched_count != None:
+            self.matched_count = matched_count
+        else:
+            self.matched_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!32s", self.name))
+        packed.append(util.pack_wc_bmap(self.wildcards))
+        packed.append(struct.pack("!L", self.max_entries))
+        packed.append(struct.pack("!L", self.active_count))
+        packed.append(struct.pack("!Q", self.lookup_count))
+        packed.append(struct.pack("!Q", self.matched_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_entry()
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.name = reader.read("!32s")[0].rstrip("\x00")
+        obj.wildcards = util.unpack_wc_bmap(reader)
+        obj.max_entries = reader.read("!L")[0]
+        obj.active_count = reader.read("!L")[0]
+        obj.lookup_count = reader.read("!Q")[0]
+        obj.matched_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.name != other.name: return False
+        if self.wildcards != other.wildcards: return False
+        if self.max_entries != other.max_entries: return False
+        if self.active_count != other.active_count: return False
+        if self.lookup_count != other.lookup_count: return False
+        if self.matched_count != other.matched_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("wildcards = ");
+                q.text(util.pretty_wildcards(self.wildcards))
+                q.text(","); q.breakable()
+                q.text("max_entries = ");
+                q.text("%#x" % self.max_entries)
+                q.text(","); q.breakable()
+                q.text("active_count = ");
+                q.text("%#x" % self.active_count)
+                q.text(","); q.breakable()
+                q.text("lookup_count = ");
+                q.text("%#x" % self.lookup_count)
+                q.text(","); q.breakable()
+                q.text("matched_count = ");
+                q.text("%#x" % self.matched_count)
+            q.breakable()
+        q.text('}')
+
+
+
+match = match_v1
diff --git a/Fabric/Utilities/src/python/loxi/of10/const.py b/Fabric/Utilities/src/python/loxi/of10/const.py
new file mode 100644
index 0000000..27d4c76
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of10/const.py
@@ -0,0 +1,538 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template const.py
+# Do not modify
+
+OFP_VERSION = 1
+
+# Identifiers from group macro_definitions
+OFP_MAX_TABLE_NAME_LEN = 32
+OFP_MAX_PORT_NAME_LEN = 16
+OFP_TCP_PORT = 6653
+OFP_SSL_PORT = 6653
+OFP_ETH_ALEN = 6
+OFP_DEFAULT_MISS_SEND_LEN = 128
+OFP_VLAN_NONE = 65535
+OFPFW_ICMP_TYPE = 64
+OFPFW_ICMP_CODE = 128
+OFP_DL_TYPE_ETH2_CUTOFF = 1536
+OFP_DL_TYPE_NOT_ETH_TYPE = 1535
+OFP_FLOW_PERMANENT = 0
+OFP_DEFAULT_PRIORITY = 32768
+DESC_STR_LEN = 256
+SERIAL_NUM_LEN = 32
+OFPQ_ALL = 4294967295
+OFPQ_MIN_RATE_UNCFG = 65535
+
+# Identifiers from group of_bsn_pdu_slot_num
+BSN_PDU_SLOT_NUM_ANY = 255
+
+of_bsn_pdu_slot_num_map = {
+    255: 'BSN_PDU_SLOT_NUM_ANY',
+}
+
+# Identifiers from group ofp_action_type
+OFPAT_OUTPUT = 0
+OFPAT_SET_VLAN_VID = 1
+OFPAT_SET_VLAN_PCP = 2
+OFPAT_STRIP_VLAN = 3
+OFPAT_SET_DL_SRC = 4
+OFPAT_SET_DL_DST = 5
+OFPAT_SET_NW_SRC = 6
+OFPAT_SET_NW_DST = 7
+OFPAT_SET_NW_TOS = 8
+OFPAT_SET_TP_SRC = 9
+OFPAT_SET_TP_DST = 10
+OFPAT_ENQUEUE = 11
+OFPAT_EXPERIMENTER = 65535
+
+ofp_action_type_map = {
+    0: 'OFPAT_OUTPUT',
+    1: 'OFPAT_SET_VLAN_VID',
+    2: 'OFPAT_SET_VLAN_PCP',
+    3: 'OFPAT_STRIP_VLAN',
+    4: 'OFPAT_SET_DL_SRC',
+    5: 'OFPAT_SET_DL_DST',
+    6: 'OFPAT_SET_NW_SRC',
+    7: 'OFPAT_SET_NW_DST',
+    8: 'OFPAT_SET_NW_TOS',
+    9: 'OFPAT_SET_TP_SRC',
+    10: 'OFPAT_SET_TP_DST',
+    11: 'OFPAT_ENQUEUE',
+    65535: 'OFPAT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_bad_action_code
+OFPBAC_BAD_TYPE = 0
+OFPBAC_BAD_LEN = 1
+OFPBAC_BAD_EXPERIMENTER = 2
+OFPBAC_BAD_EXPERIMENTER_TYPE = 3
+OFPBAC_BAD_OUT_PORT = 4
+OFPBAC_BAD_ARGUMENT = 5
+OFPBAC_EPERM = 6
+OFPBAC_TOO_MANY = 7
+OFPBAC_BAD_QUEUE = 8
+
+ofp_bad_action_code_map = {
+    0: 'OFPBAC_BAD_TYPE',
+    1: 'OFPBAC_BAD_LEN',
+    2: 'OFPBAC_BAD_EXPERIMENTER',
+    3: 'OFPBAC_BAD_EXPERIMENTER_TYPE',
+    4: 'OFPBAC_BAD_OUT_PORT',
+    5: 'OFPBAC_BAD_ARGUMENT',
+    6: 'OFPBAC_EPERM',
+    7: 'OFPBAC_TOO_MANY',
+    8: 'OFPBAC_BAD_QUEUE',
+}
+
+# Identifiers from group ofp_bad_request_code
+OFPBRC_BAD_VERSION = 0
+OFPBRC_BAD_TYPE = 1
+OFPBRC_BAD_STAT = 2
+OFPBRC_BAD_EXPERIMENTER = 3
+OFPBRC_BAD_SUBTYPE = 4
+OFPBRC_EPERM = 5
+OFPBRC_BAD_LEN = 6
+OFPBRC_BUFFER_EMPTY = 7
+OFPBRC_BUFFER_UNKNOWN = 8
+
+ofp_bad_request_code_map = {
+    0: 'OFPBRC_BAD_VERSION',
+    1: 'OFPBRC_BAD_TYPE',
+    2: 'OFPBRC_BAD_STAT',
+    3: 'OFPBRC_BAD_EXPERIMENTER',
+    4: 'OFPBRC_BAD_SUBTYPE',
+    5: 'OFPBRC_EPERM',
+    6: 'OFPBRC_BAD_LEN',
+    7: 'OFPBRC_BUFFER_EMPTY',
+    8: 'OFPBRC_BUFFER_UNKNOWN',
+}
+
+# Identifiers from group ofp_bsn_vport_l2gre_flags
+OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID = 1
+OF_BSN_VPORT_L2GRE_DSCP_ASSIGN = 2
+OF_BSN_VPORT_L2GRE_DSCP_COPY = 4
+OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID = 8
+OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID = 16
+
+ofp_bsn_vport_l2gre_flags_map = {
+    1: 'OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID',
+    2: 'OF_BSN_VPORT_L2GRE_DSCP_ASSIGN',
+    4: 'OF_BSN_VPORT_L2GRE_DSCP_COPY',
+    8: 'OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID',
+    16: 'OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID',
+}
+
+# Identifiers from group ofp_bsn_vport_q_in_q_untagged
+OF_BSN_VPORT_Q_IN_Q_UNTAGGED = 65535
+
+ofp_bsn_vport_q_in_q_untagged_map = {
+    65535: 'OF_BSN_VPORT_Q_IN_Q_UNTAGGED',
+}
+
+# Identifiers from group ofp_bsn_vport_status
+OF_BSN_VPORT_STATUS_OK = 0
+OF_BSN_VPORT_STATUS_FAILED = 1
+
+ofp_bsn_vport_status_map = {
+    0: 'OF_BSN_VPORT_STATUS_OK',
+    1: 'OF_BSN_VPORT_STATUS_FAILED',
+}
+
+# Identifiers from group ofp_capabilities
+OFPC_FLOW_STATS = 1
+OFPC_TABLE_STATS = 2
+OFPC_PORT_STATS = 4
+OFPC_STP = 8
+OFPC_RESERVED = 16
+OFPC_IP_REASM = 32
+OFPC_QUEUE_STATS = 64
+OFPC_ARP_MATCH_IP = 128
+
+ofp_capabilities_map = {
+    1: 'OFPC_FLOW_STATS',
+    2: 'OFPC_TABLE_STATS',
+    4: 'OFPC_PORT_STATS',
+    8: 'OFPC_STP',
+    16: 'OFPC_RESERVED',
+    32: 'OFPC_IP_REASM',
+    64: 'OFPC_QUEUE_STATS',
+    128: 'OFPC_ARP_MATCH_IP',
+}
+
+# Identifiers from group ofp_config_flags
+OFPC_FRAG_NORMAL = 0
+OFPC_FRAG_DROP = 1
+OFPC_FRAG_REASM = 2
+OFPC_FRAG_MASK = 3
+
+ofp_config_flags_map = {
+    0: 'OFPC_FRAG_NORMAL',
+    1: 'OFPC_FRAG_DROP',
+    2: 'OFPC_FRAG_REASM',
+    3: 'OFPC_FRAG_MASK',
+}
+
+# Identifiers from group ofp_error_type
+OFPET_HELLO_FAILED = 0
+OFPET_BAD_REQUEST = 1
+OFPET_BAD_ACTION = 2
+OFPET_FLOW_MOD_FAILED = 3
+OFPET_PORT_MOD_FAILED = 4
+OFPET_QUEUE_OP_FAILED = 5
+
+ofp_error_type_map = {
+    0: 'OFPET_HELLO_FAILED',
+    1: 'OFPET_BAD_REQUEST',
+    2: 'OFPET_BAD_ACTION',
+    3: 'OFPET_FLOW_MOD_FAILED',
+    4: 'OFPET_PORT_MOD_FAILED',
+    5: 'OFPET_QUEUE_OP_FAILED',
+}
+
+# Identifiers from group ofp_flow_mod_command
+OFPFC_ADD = 0
+OFPFC_MODIFY = 1
+OFPFC_MODIFY_STRICT = 2
+OFPFC_DELETE = 3
+OFPFC_DELETE_STRICT = 4
+
+ofp_flow_mod_command_map = {
+    0: 'OFPFC_ADD',
+    1: 'OFPFC_MODIFY',
+    2: 'OFPFC_MODIFY_STRICT',
+    3: 'OFPFC_DELETE',
+    4: 'OFPFC_DELETE_STRICT',
+}
+
+# Identifiers from group ofp_flow_mod_failed_code
+OFPFMFC_ALL_TABLES_FULL = 0
+OFPFMFC_OVERLAP = 1
+OFPFMFC_EPERM = 2
+OFPFMFC_BAD_EMERG_TIMEOUT = 3
+OFPFMFC_BAD_COMMAND = 4
+OFPFMFC_UNSUPPORTED = 5
+
+ofp_flow_mod_failed_code_map = {
+    0: 'OFPFMFC_ALL_TABLES_FULL',
+    1: 'OFPFMFC_OVERLAP',
+    2: 'OFPFMFC_EPERM',
+    3: 'OFPFMFC_BAD_EMERG_TIMEOUT',
+    4: 'OFPFMFC_BAD_COMMAND',
+    5: 'OFPFMFC_UNSUPPORTED',
+}
+
+# Identifiers from group ofp_flow_mod_flags
+OFPFF_SEND_FLOW_REM = 1
+OFPFF_CHECK_OVERLAP = 2
+OFPFF_EMERG = 4
+
+ofp_flow_mod_flags_map = {
+    1: 'OFPFF_SEND_FLOW_REM',
+    2: 'OFPFF_CHECK_OVERLAP',
+    4: 'OFPFF_EMERG',
+}
+
+# Identifiers from group ofp_flow_removed_reason
+OFPRR_IDLE_TIMEOUT = 0
+OFPRR_HARD_TIMEOUT = 1
+OFPRR_DELETE = 2
+
+ofp_flow_removed_reason_map = {
+    0: 'OFPRR_IDLE_TIMEOUT',
+    1: 'OFPRR_HARD_TIMEOUT',
+    2: 'OFPRR_DELETE',
+}
+
+# Identifiers from group ofp_flow_wildcards
+OFPFW_IN_PORT = 1
+OFPFW_DL_VLAN = 2
+OFPFW_DL_SRC = 4
+OFPFW_NW_DST_BITS = 6
+OFPFW_NW_SRC_BITS = 6
+OFPFW_NW_SRC_SHIFT = 8
+OFPFW_DL_DST = 8
+OFPFW_NW_DST_SHIFT = 14
+OFPFW_DL_TYPE = 16
+OFPFW_NW_PROTO = 32
+OFPFW_TP_SRC = 64
+OFPFW_TP_DST = 128
+OFPFW_NW_SRC_ALL = 8192
+OFPFW_NW_SRC_MASK = 16128
+OFPFW_NW_DST_ALL = 524288
+OFPFW_NW_DST_MASK = 1032192
+OFPFW_DL_VLAN_PCP = 1048576
+OFPFW_NW_TOS = 2097152
+OFPFW_ALL = 4194303
+
+ofp_flow_wildcards_map = {
+    1: 'OFPFW_IN_PORT',
+    2: 'OFPFW_DL_VLAN',
+    4: 'OFPFW_DL_SRC',
+    8: 'OFPFW_DL_DST',
+    16: 'OFPFW_DL_TYPE',
+    32: 'OFPFW_NW_PROTO',
+    64: 'OFPFW_TP_SRC',
+    128: 'OFPFW_TP_DST',
+    1048576: 'OFPFW_DL_VLAN_PCP',
+    2097152: 'OFPFW_NW_TOS',
+}
+
+# Identifiers from group ofp_hello_failed_code
+OFPHFC_INCOMPATIBLE = 0
+OFPHFC_EPERM = 1
+
+ofp_hello_failed_code_map = {
+    0: 'OFPHFC_INCOMPATIBLE',
+    1: 'OFPHFC_EPERM',
+}
+
+# Identifiers from group ofp_nicira_controller_role
+NX_ROLE_OTHER = 0
+NX_ROLE_MASTER = 1
+NX_ROLE_SLAVE = 2
+
+ofp_nicira_controller_role_map = {
+    0: 'NX_ROLE_OTHER',
+    1: 'NX_ROLE_MASTER',
+    2: 'NX_ROLE_SLAVE',
+}
+
+# Identifiers from group ofp_packet_in_reason
+OFPR_NO_MATCH = 0
+OFPR_ACTION = 1
+
+ofp_packet_in_reason_map = {
+    0: 'OFPR_NO_MATCH',
+    1: 'OFPR_ACTION',
+}
+
+# Identifiers from group ofp_port
+OFPP_MAX = 0xff00
+OFPP_IN_PORT = 0xfff8
+OFPP_TABLE = 0xfff9
+OFPP_NORMAL = 0xfffa
+OFPP_FLOOD = 0xfffb
+OFPP_ALL = 0xfffc
+OFPP_CONTROLLER = 0xfffd
+OFPP_LOCAL = 0xfffe
+OFPP_NONE = 0xffff
+
+ofp_port_map = {
+    0xff00: 'OFPP_MAX',
+    0xfff8: 'OFPP_IN_PORT',
+    0xfff9: 'OFPP_TABLE',
+    0xfffa: 'OFPP_NORMAL',
+    0xfffb: 'OFPP_FLOOD',
+    0xfffc: 'OFPP_ALL',
+    0xfffd: 'OFPP_CONTROLLER',
+    0xfffe: 'OFPP_LOCAL',
+    0xffff: 'OFPP_NONE',
+}
+
+# Identifiers from group ofp_port_config
+OFPPC_PORT_DOWN = 1
+OFPPC_NO_STP = 2
+OFPPC_NO_RECV = 4
+OFPPC_NO_RECV_STP = 8
+OFPPC_NO_FLOOD = 16
+OFPPC_NO_FWD = 32
+OFPPC_NO_PACKET_IN = 64
+OFPPC_BSN_MIRROR_DEST = 2147483648
+
+ofp_port_config_map = {
+    1: 'OFPPC_PORT_DOWN',
+    2: 'OFPPC_NO_STP',
+    4: 'OFPPC_NO_RECV',
+    8: 'OFPPC_NO_RECV_STP',
+    16: 'OFPPC_NO_FLOOD',
+    32: 'OFPPC_NO_FWD',
+    64: 'OFPPC_NO_PACKET_IN',
+    2147483648: 'OFPPC_BSN_MIRROR_DEST',
+}
+
+# Identifiers from group ofp_port_features
+OFPPF_10MB_HD = 1
+OFPPF_10MB_FD = 2
+OFPPF_100MB_HD = 4
+OFPPF_100MB_FD = 8
+OFPPF_1GB_HD = 16
+OFPPF_1GB_FD = 32
+OFPPF_10GB_FD = 64
+OFPPF_COPPER = 128
+OFPPF_FIBER = 256
+OFPPF_AUTONEG = 512
+OFPPF_PAUSE = 1024
+OFPPF_PAUSE_ASYM = 2048
+
+ofp_port_features_map = {
+    1: 'OFPPF_10MB_HD',
+    2: 'OFPPF_10MB_FD',
+    4: 'OFPPF_100MB_HD',
+    8: 'OFPPF_100MB_FD',
+    16: 'OFPPF_1GB_HD',
+    32: 'OFPPF_1GB_FD',
+    64: 'OFPPF_10GB_FD',
+    128: 'OFPPF_COPPER',
+    256: 'OFPPF_FIBER',
+    512: 'OFPPF_AUTONEG',
+    1024: 'OFPPF_PAUSE',
+    2048: 'OFPPF_PAUSE_ASYM',
+}
+
+# Identifiers from group ofp_port_mod_failed_code
+OFPPMFC_BAD_PORT = 0
+OFPPMFC_BAD_HW_ADDR = 1
+
+ofp_port_mod_failed_code_map = {
+    0: 'OFPPMFC_BAD_PORT',
+    1: 'OFPPMFC_BAD_HW_ADDR',
+}
+
+# Identifiers from group ofp_port_reason
+OFPPR_ADD = 0
+OFPPR_DELETE = 1
+OFPPR_MODIFY = 2
+
+ofp_port_reason_map = {
+    0: 'OFPPR_ADD',
+    1: 'OFPPR_DELETE',
+    2: 'OFPPR_MODIFY',
+}
+
+# Identifiers from group ofp_port_state
+OFPPS_LINK_DOWN = 1
+OFPPS_STP_LISTEN = 0
+OFPPS_STP_LEARN = 256
+OFPPS_STP_FORWARD = 512
+OFPPS_STP_BLOCK = 768
+OFPPS_STP_MASK = 768
+
+ofp_port_state_map = {
+    1: 'OFPPS_LINK_DOWN',
+    0: 'OFPPS_STP_LISTEN',
+    256: 'OFPPS_STP_LEARN',
+    512: 'OFPPS_STP_FORWARD',
+    768: 'OFPPS_STP_BLOCK',
+    768: 'OFPPS_STP_MASK',
+}
+
+# Identifiers from group ofp_queue_op_failed_code
+OFPQOFC_BAD_PORT = 0
+OFPQOFC_BAD_QUEUE = 1
+OFPQOFC_EPERM = 2
+
+ofp_queue_op_failed_code_map = {
+    0: 'OFPQOFC_BAD_PORT',
+    1: 'OFPQOFC_BAD_QUEUE',
+    2: 'OFPQOFC_EPERM',
+}
+
+# Identifiers from group ofp_queue_properties
+OFPQT_NONE = 0
+OFPQT_MIN_RATE = 1
+
+ofp_queue_properties_map = {
+    0: 'OFPQT_NONE',
+    1: 'OFPQT_MIN_RATE',
+}
+
+# Identifiers from group ofp_stats_reply_flags
+OFPSF_REPLY_MORE = 1
+
+ofp_stats_reply_flags_map = {
+    1: 'OFPSF_REPLY_MORE',
+}
+
+# Identifiers from group ofp_stats_request_flags
+
+ofp_stats_request_flags_map = {
+}
+
+# Identifiers from group ofp_stats_type
+OFPST_DESC = 0
+OFPST_FLOW = 1
+OFPST_AGGREGATE = 2
+OFPST_TABLE = 3
+OFPST_PORT = 4
+OFPST_QUEUE = 5
+OFPST_EXPERIMENTER = 65535
+
+ofp_stats_type_map = {
+    0: 'OFPST_DESC',
+    1: 'OFPST_FLOW',
+    2: 'OFPST_AGGREGATE',
+    3: 'OFPST_TABLE',
+    4: 'OFPST_PORT',
+    5: 'OFPST_QUEUE',
+    65535: 'OFPST_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_type
+OFPT_HELLO = 0
+OFPT_ERROR = 1
+OFPT_ECHO_REQUEST = 2
+OFPT_ECHO_REPLY = 3
+OFPT_EXPERIMENTER = 4
+OFPT_FEATURES_REQUEST = 5
+OFPT_FEATURES_REPLY = 6
+OFPT_GET_CONFIG_REQUEST = 7
+OFPT_GET_CONFIG_REPLY = 8
+OFPT_SET_CONFIG = 9
+OFPT_PACKET_IN = 10
+OFPT_FLOW_REMOVED = 11
+OFPT_PORT_STATUS = 12
+OFPT_PACKET_OUT = 13
+OFPT_FLOW_MOD = 14
+OFPT_PORT_MOD = 15
+OFPT_STATS_REQUEST = 16
+OFPT_STATS_REPLY = 17
+OFPT_BARRIER_REQUEST = 18
+OFPT_BARRIER_REPLY = 19
+OFPT_QUEUE_GET_CONFIG_REQUEST = 20
+OFPT_QUEUE_GET_CONFIG_REPLY = 21
+
+ofp_type_map = {
+    0: 'OFPT_HELLO',
+    1: 'OFPT_ERROR',
+    2: 'OFPT_ECHO_REQUEST',
+    3: 'OFPT_ECHO_REPLY',
+    4: 'OFPT_EXPERIMENTER',
+    5: 'OFPT_FEATURES_REQUEST',
+    6: 'OFPT_FEATURES_REPLY',
+    7: 'OFPT_GET_CONFIG_REQUEST',
+    8: 'OFPT_GET_CONFIG_REPLY',
+    9: 'OFPT_SET_CONFIG',
+    10: 'OFPT_PACKET_IN',
+    11: 'OFPT_FLOW_REMOVED',
+    12: 'OFPT_PORT_STATUS',
+    13: 'OFPT_PACKET_OUT',
+    14: 'OFPT_FLOW_MOD',
+    15: 'OFPT_PORT_MOD',
+    16: 'OFPT_STATS_REQUEST',
+    17: 'OFPT_STATS_REPLY',
+    18: 'OFPT_BARRIER_REQUEST',
+    19: 'OFPT_BARRIER_REPLY',
+    20: 'OFPT_QUEUE_GET_CONFIG_REQUEST',
+    21: 'OFPT_QUEUE_GET_CONFIG_REPLY',
+}
+
diff --git a/Fabric/Utilities/src/python/loxi/of10/message.py b/Fabric/Utilities/src/python/loxi/of10/message.py
new file mode 100644
index 0000000..5ffc5f3
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of10/message.py
@@ -0,0 +1,7553 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of10']
+
+class message(loxi.OFObject):
+    subtypes = {}
+
+    version = 1
+
+    def __init__(self, type=None, xid=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 1)
+        subclass = message.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = message()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        obj.type = reader.read("!B")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("message {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+
+class stats_reply(message):
+    subtypes = {}
+
+    version = 1
+    type = 17
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[17] = stats_reply
+
+class aggregate_stats_reply(stats_reply):
+    version = 1
+    type = 17
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, packet_count=None, byte_count=None, flow_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if flow_count != None:
+            self.flow_count = flow_count
+        else:
+            self.flow_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(struct.pack("!L", self.flow_count))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.flow_count = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.flow_count != other.flow_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("flow_count = ");
+                q.text("%#x" % self.flow_count)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[2] = aggregate_stats_reply
+
+class stats_request(message):
+    subtypes = {}
+
+    version = 1
+    type = 16
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[16] = stats_request
+
+class aggregate_stats_request(stats_request):
+    version = 1
+    type = 16
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, match=None, table_id=None, out_port=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(util.pack_port_no(self.out_port))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.out_port = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[2] = aggregate_stats_request
+
+class error_msg(message):
+    subtypes = {}
+
+    version = 1
+    type = 1
+
+    def __init__(self, xid=None, err_type=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if err_type != None:
+            self.err_type = err_type
+        else:
+            self.err_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = error_msg.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.err_type = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.err_type != other.err_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[1] = error_msg
+
+class bad_action_error_msg(error_msg):
+    version = 1
+    type = 1
+    err_type = 2
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_action_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 2)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_action_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[2] = bad_action_error_msg
+
+class bad_request_error_msg(error_msg):
+    version = 1
+    type = 1
+    err_type = 1
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_request_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 1)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_request_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[1] = bad_request_error_msg
+
+class barrier_reply(message):
+    version = 1
+    type = 19
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[19] = barrier_reply
+
+class barrier_request(message):
+    version = 1
+    type = 18
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[18] = barrier_request
+
+class experimenter(message):
+    subtypes = {}
+
+    version = 1
+    type = 4
+
+    def __init__(self, xid=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[4] = experimenter
+
+class bsn_header(experimenter):
+    subtypes = {}
+
+    version = 1
+    type = 4
+    experimenter = 6035143
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = bsn_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn_header
+
+class bsn_bw_clear_data_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 22
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 22)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[22] = bsn_bw_clear_data_reply
+
+class bsn_bw_clear_data_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 21)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[21] = bsn_bw_clear_data_request
+
+class bsn_bw_enable_get_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 20
+
+    def __init__(self, xid=None, enabled=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enabled))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 20)
+        obj.enabled = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[20] = bsn_bw_enable_get_reply
+
+class bsn_bw_enable_get_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 19
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 19)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[19] = bsn_bw_enable_get_request
+
+class bsn_bw_enable_set_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 23
+
+    def __init__(self, xid=None, enable=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 23)
+        obj.enable = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[23] = bsn_bw_enable_set_reply
+
+class bsn_bw_enable_set_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 18
+
+    def __init__(self, xid=None, enable=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 18)
+        obj.enable = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[18] = bsn_bw_enable_set_request
+
+class bsn_get_interfaces_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, interfaces=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if interfaces != None:
+            self.interfaces = interfaces
+        else:
+            self.interfaces = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.interfaces))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.interfaces = loxi.generic_util.unpack_list(reader, ofp.common.bsn_interface.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.interfaces != other.interfaces: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("interfaces = ");
+                q.pp(self.interfaces)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[10] = bsn_get_interfaces_reply
+
+class bsn_get_interfaces_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[9] = bsn_get_interfaces_request
+
+class bsn_get_ip_mask_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, xid=None, index=None, mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if index != None:
+            self.index = index
+        else:
+            self.index = 0
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.index))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_ip_mask_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.index = reader.read("!B")[0]
+        reader.skip(3)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.index != other.index: return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_ip_mask_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("index = ");
+                q.text("%#x" % self.index)
+                q.text(","); q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[2] = bsn_get_ip_mask_reply
+
+class bsn_get_ip_mask_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, xid=None, index=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if index != None:
+            self.index = index
+        else:
+            self.index = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.index))
+        packed.append('\x00' * 7)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_ip_mask_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.index = reader.read("!B")[0]
+        reader.skip(7)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.index != other.index: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_ip_mask_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("index = ");
+                q.text("%#x" % self.index)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[1] = bsn_get_ip_mask_request
+
+class bsn_get_l2_table_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 14
+
+    def __init__(self, xid=None, l2_table_enable=None, l2_table_priority=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if l2_table_enable != None:
+            self.l2_table_enable = l2_table_enable
+        else:
+            self.l2_table_enable = 0
+        if l2_table_priority != None:
+            self.l2_table_priority = l2_table_priority
+        else:
+            self.l2_table_priority = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.l2_table_enable))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.l2_table_priority))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_l2_table_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 14)
+        obj.l2_table_enable = reader.read("!B")[0]
+        reader.skip(1)
+        obj.l2_table_priority = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.l2_table_enable != other.l2_table_enable: return False
+        if self.l2_table_priority != other.l2_table_priority: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_l2_table_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("l2_table_enable = ");
+                q.text("%#x" % self.l2_table_enable)
+                q.text(","); q.breakable()
+                q.text("l2_table_priority = ");
+                q.text("%#x" % self.l2_table_priority)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[14] = bsn_get_l2_table_reply
+
+class bsn_get_l2_table_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_l2_table_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_l2_table_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[13] = bsn_get_l2_table_request
+
+class bsn_get_mirroring_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[5] = bsn_get_mirroring_reply
+
+class bsn_get_mirroring_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[4] = bsn_get_mirroring_request
+
+class bsn_hybrid_get_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 28
+
+    def __init__(self, xid=None, hybrid_enable=None, hybrid_version=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if hybrid_enable != None:
+            self.hybrid_enable = hybrid_enable
+        else:
+            self.hybrid_enable = 0
+        if hybrid_version != None:
+            self.hybrid_version = hybrid_version
+        else:
+            self.hybrid_version = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.hybrid_enable))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.hybrid_version))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_hybrid_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 28)
+        obj.hybrid_enable = reader.read("!B")[0]
+        reader.skip(1)
+        obj.hybrid_version = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.hybrid_enable != other.hybrid_enable: return False
+        if self.hybrid_version != other.hybrid_version: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_hybrid_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("hybrid_enable = ");
+                q.text("%#x" % self.hybrid_enable)
+                q.text(","); q.breakable()
+                q.text("hybrid_version = ");
+                q.text("%#x" % self.hybrid_version)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[28] = bsn_hybrid_get_reply
+
+class bsn_hybrid_get_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 27
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_hybrid_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 27)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_hybrid_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[27] = bsn_hybrid_get_request
+
+class bsn_pdu_rx_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 34
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 34)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[34] = bsn_pdu_rx_reply
+
+class bsn_pdu_rx_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 33
+
+    def __init__(self, xid=None, timeout_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if timeout_ms != None:
+            self.timeout_ms = timeout_ms
+        else:
+            self.timeout_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.timeout_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 33)
+        obj.timeout_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.timeout_ms != other.timeout_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("timeout_ms = ");
+                q.text("%#x" % self.timeout_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[33] = bsn_pdu_rx_request
+
+class bsn_pdu_rx_timeout(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 35
+
+    def __init__(self, xid=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_timeout()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 35)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[35] = bsn_pdu_rx_timeout
+
+class bsn_pdu_tx_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 32
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 32)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[32] = bsn_pdu_tx_reply
+
+class bsn_pdu_tx_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 31
+
+    def __init__(self, xid=None, tx_interval_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if tx_interval_ms != None:
+            self.tx_interval_ms = tx_interval_ms
+        else:
+            self.tx_interval_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.tx_interval_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 31)
+        obj.tx_interval_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.tx_interval_ms != other.tx_interval_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("tx_interval_ms = ");
+                q.text("%#x" % self.tx_interval_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[31] = bsn_pdu_tx_request
+
+class bsn_set_ip_mask(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 0
+
+    def __init__(self, xid=None, index=None, mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if index != None:
+            self.index = index
+        else:
+            self.index = 0
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.index))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_ip_mask()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 0)
+        obj.index = reader.read("!B")[0]
+        reader.skip(3)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.index != other.index: return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_ip_mask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("index = ");
+                q.text("%#x" % self.index)
+                q.text(","); q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[0] = bsn_set_ip_mask
+
+class bsn_set_l2_table_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 24
+
+    def __init__(self, xid=None, l2_table_enable=None, l2_table_priority=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if l2_table_enable != None:
+            self.l2_table_enable = l2_table_enable
+        else:
+            self.l2_table_enable = 0
+        if l2_table_priority != None:
+            self.l2_table_priority = l2_table_priority
+        else:
+            self.l2_table_priority = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.l2_table_enable))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.l2_table_priority))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_l2_table_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 24)
+        obj.l2_table_enable = reader.read("!B")[0]
+        reader.skip(1)
+        obj.l2_table_priority = reader.read("!H")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.l2_table_enable != other.l2_table_enable: return False
+        if self.l2_table_priority != other.l2_table_priority: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_l2_table_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("l2_table_enable = ");
+                q.text("%#x" % self.l2_table_enable)
+                q.text(","); q.breakable()
+                q.text("l2_table_priority = ");
+                q.text("%#x" % self.l2_table_priority)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[24] = bsn_set_l2_table_reply
+
+class bsn_set_l2_table_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self, xid=None, l2_table_enable=None, l2_table_priority=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if l2_table_enable != None:
+            self.l2_table_enable = l2_table_enable
+        else:
+            self.l2_table_enable = 0
+        if l2_table_priority != None:
+            self.l2_table_priority = l2_table_priority
+        else:
+            self.l2_table_priority = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.l2_table_enable))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.l2_table_priority))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_l2_table_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        obj.l2_table_enable = reader.read("!B")[0]
+        reader.skip(1)
+        obj.l2_table_priority = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.l2_table_enable != other.l2_table_enable: return False
+        if self.l2_table_priority != other.l2_table_priority: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_l2_table_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("l2_table_enable = ");
+                q.text("%#x" % self.l2_table_enable)
+                q.text(","); q.breakable()
+                q.text("l2_table_priority = ");
+                q.text("%#x" % self.l2_table_priority)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[12] = bsn_set_l2_table_request
+
+class bsn_set_mirroring(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_mirroring()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_mirroring {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[3] = bsn_set_mirroring
+
+class bsn_set_pktin_suppression_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 25
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 25)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[25] = bsn_set_pktin_suppression_reply
+
+class bsn_set_pktin_suppression_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, enabled=None, idle_timeout=None, hard_timeout=None, priority=None, cookie=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.enabled))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!Q", self.cookie))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.enabled = reader.read("!B")[0]
+        reader.skip(1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.cookie = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.cookie != other.cookie: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[11] = bsn_set_pktin_suppression_request
+
+class bsn_shell_command(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self, xid=None, service=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if service != None:
+            self.service = service
+        else:
+            self.service = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.service))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_shell_command()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        obj.service = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.service != other.service: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_shell_command {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("service = ");
+                q.text("%#x" % self.service)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[6] = bsn_shell_command
+
+class bsn_shell_output(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_shell_output()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_shell_output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[7] = bsn_shell_output
+
+class bsn_shell_status(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_shell_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_shell_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[8] = bsn_shell_status
+
+class experimenter_stats_reply(stats_reply):
+    subtypes = {}
+
+    version = 1
+    type = 17
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = experimenter_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[65535] = experimenter_stats_reply
+
+class bsn_stats_reply(experimenter_stats_reply):
+    subtypes = {}
+
+    version = 1
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_reply.subtypes[6035143] = bsn_stats_reply
+
+class experimenter_stats_request(stats_request):
+    subtypes = {}
+
+    version = 1
+    type = 16
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = experimenter_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[65535] = experimenter_stats_request
+
+class bsn_stats_request(experimenter_stats_request):
+    subtypes = {}
+
+    version = 1
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_request.subtypes[6035143] = bsn_stats_request
+
+class bsn_virtual_port_create_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, status=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.status = reader.read("!L")[0]
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[16] = bsn_virtual_port_create_reply
+
+class bsn_virtual_port_create_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, vport=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport != None:
+            self.vport = vport
+        else:
+            self.vport = ofp.bsn_vport()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.vport.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.vport = ofp.bsn_vport.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport != other.vport: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport = ");
+                q.pp(self.vport)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[15] = bsn_virtual_port_create_request
+
+class bsn_virtual_port_remove_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 26
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 26)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[26] = bsn_virtual_port_remove_reply
+
+class bsn_virtual_port_remove_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 17
+
+    def __init__(self, xid=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 17)
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[17] = bsn_virtual_port_remove_request
+
+class desc_stats_reply(stats_reply):
+    version = 1
+    type = 17
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None, mfr_desc=None, hw_desc=None, sw_desc=None, serial_num=None, dp_desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if mfr_desc != None:
+            self.mfr_desc = mfr_desc
+        else:
+            self.mfr_desc = ""
+        if hw_desc != None:
+            self.hw_desc = hw_desc
+        else:
+            self.hw_desc = ""
+        if sw_desc != None:
+            self.sw_desc = sw_desc
+        else:
+            self.sw_desc = ""
+        if serial_num != None:
+            self.serial_num = serial_num
+        else:
+            self.serial_num = ""
+        if dp_desc != None:
+            self.dp_desc = dp_desc
+        else:
+            self.dp_desc = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!256s", self.mfr_desc))
+        packed.append(struct.pack("!256s", self.hw_desc))
+        packed.append(struct.pack("!256s", self.sw_desc))
+        packed.append(struct.pack("!32s", self.serial_num))
+        packed.append(struct.pack("!256s", self.dp_desc))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        obj.mfr_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.hw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.sw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.serial_num = reader.read("!32s")[0].rstrip("\x00")
+        obj.dp_desc = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.mfr_desc != other.mfr_desc: return False
+        if self.hw_desc != other.hw_desc: return False
+        if self.sw_desc != other.sw_desc: return False
+        if self.serial_num != other.serial_num: return False
+        if self.dp_desc != other.dp_desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("mfr_desc = ");
+                q.pp(self.mfr_desc)
+                q.text(","); q.breakable()
+                q.text("hw_desc = ");
+                q.pp(self.hw_desc)
+                q.text(","); q.breakable()
+                q.text("sw_desc = ");
+                q.pp(self.sw_desc)
+                q.text(","); q.breakable()
+                q.text("serial_num = ");
+                q.pp(self.serial_num)
+                q.text(","); q.breakable()
+                q.text("dp_desc = ");
+                q.pp(self.dp_desc)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[0] = desc_stats_reply
+
+class desc_stats_request(stats_request):
+    version = 1
+    type = 16
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[0] = desc_stats_request
+
+class echo_reply(message):
+    version = 1
+    type = 3
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[3] = echo_reply
+
+class echo_request(message):
+    version = 1
+    type = 2
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[2] = echo_request
+
+class features_reply(message):
+    version = 1
+    type = 6
+
+    def __init__(self, xid=None, datapath_id=None, n_buffers=None, n_tables=None, capabilities=None, actions=None, ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if datapath_id != None:
+            self.datapath_id = datapath_id
+        else:
+            self.datapath_id = 0
+        if n_buffers != None:
+            self.n_buffers = n_buffers
+        else:
+            self.n_buffers = 0
+        if n_tables != None:
+            self.n_tables = n_tables
+        else:
+            self.n_tables = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = 0
+        if ports != None:
+            self.ports = ports
+        else:
+            self.ports = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.datapath_id))
+        packed.append(struct.pack("!L", self.n_buffers))
+        packed.append(struct.pack("!B", self.n_tables))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.actions))
+        packed.append(loxi.generic_util.pack_list(self.ports))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.datapath_id = reader.read("!Q")[0]
+        obj.n_buffers = reader.read("!L")[0]
+        obj.n_tables = reader.read("!B")[0]
+        reader.skip(3)
+        obj.capabilities = reader.read("!L")[0]
+        obj.actions = reader.read("!L")[0]
+        obj.ports = loxi.generic_util.unpack_list(reader, ofp.common.port_desc.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.datapath_id != other.datapath_id: return False
+        if self.n_buffers != other.n_buffers: return False
+        if self.n_tables != other.n_tables: return False
+        if self.capabilities != other.capabilities: return False
+        if self.actions != other.actions: return False
+        if self.ports != other.ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("datapath_id = ");
+                q.text("%#x" % self.datapath_id)
+                q.text(","); q.breakable()
+                q.text("n_buffers = ");
+                q.text("%#x" % self.n_buffers)
+                q.text(","); q.breakable()
+                q.text("n_tables = ");
+                q.text("%#x" % self.n_tables)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.text("%#x" % self.actions)
+                q.text(","); q.breakable()
+                q.text("ports = ");
+                q.pp(self.ports)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[6] = features_reply
+
+class features_request(message):
+    version = 1
+    type = 5
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[5] = features_request
+
+class flow_mod(message):
+    subtypes = {}
+
+    version = 1
+    type = 14
+
+    def __init__(self, xid=None, match=None, cookie=None, _command=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, flags=None, actions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if _command != None:
+            self._command = _command
+        else:
+            self._command = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 56)
+        subclass = flow_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = flow_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.cookie = reader.read("!Q")[0]
+        obj._command = util.unpack_fm_cmd(reader)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.flags = reader.read("!H")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.match != other.match: return False
+        if self.cookie != other.cookie: return False
+        if self._command != other._command: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.flags != other.flags: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[14] = flow_mod
+
+class flow_add(flow_mod):
+    version = 1
+    type = 14
+    _command = 0
+
+    def __init__(self, xid=None, match=None, cookie=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, flags=None, actions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.cookie = reader.read("!Q")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 0)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.flags = reader.read("!H")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.match != other.match: return False
+        if self.cookie != other.cookie: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.flags != other.flags: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[0] = flow_add
+
+class flow_delete(flow_mod):
+    version = 1
+    type = 14
+    _command = 3
+
+    def __init__(self, xid=None, match=None, cookie=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, flags=None, actions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.cookie = reader.read("!Q")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 3)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.flags = reader.read("!H")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.match != other.match: return False
+        if self.cookie != other.cookie: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.flags != other.flags: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[3] = flow_delete
+
+class flow_delete_strict(flow_mod):
+    version = 1
+    type = 14
+    _command = 4
+
+    def __init__(self, xid=None, match=None, cookie=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, flags=None, actions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.cookie = reader.read("!Q")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 4)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.flags = reader.read("!H")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.match != other.match: return False
+        if self.cookie != other.cookie: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.flags != other.flags: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[4] = flow_delete_strict
+
+class flow_mod_failed_error_msg(error_msg):
+    version = 1
+    type = 1
+    err_type = 3
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 3)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[3] = flow_mod_failed_error_msg
+
+class flow_modify(flow_mod):
+    version = 1
+    type = 14
+    _command = 1
+
+    def __init__(self, xid=None, match=None, cookie=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, flags=None, actions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.cookie = reader.read("!Q")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.flags = reader.read("!H")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.match != other.match: return False
+        if self.cookie != other.cookie: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.flags != other.flags: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[1] = flow_modify
+
+class flow_modify_strict(flow_mod):
+    version = 1
+    type = 14
+    _command = 2
+
+    def __init__(self, xid=None, match=None, cookie=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, flags=None, actions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.cookie = reader.read("!Q")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 2)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.flags = reader.read("!H")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.match != other.match: return False
+        if self.cookie != other.cookie: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.flags != other.flags: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[2] = flow_modify_strict
+
+class flow_removed(message):
+    version = 1
+    type = 11
+
+    def __init__(self, xid=None, match=None, cookie=None, priority=None, reason=None, duration_sec=None, duration_nsec=None, idle_timeout=None, packet_count=None, byte_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_removed()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.cookie = reader.read("!Q")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(1)
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        reader.skip(2)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.match != other.match: return False
+        if self.cookie != other.cookie: return False
+        if self.priority != other.priority: return False
+        if self.reason != other.reason: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_removed {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[11] = flow_removed
+
+class flow_stats_reply(stats_reply):
+    version = 1
+    type = 17
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.flow_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[1] = flow_stats_reply
+
+class flow_stats_request(stats_request):
+    version = 1
+    type = 16
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, match=None, table_id=None, out_port=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(util.pack_port_no(self.out_port))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.out_port = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[1] = flow_stats_request
+
+class get_config_reply(message):
+    version = 1
+    type = 8
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[8] = get_config_reply
+
+class get_config_request(message):
+    version = 1
+    type = 7
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[7] = get_config_request
+
+class hello(message):
+    version = 1
+    type = 0
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[0] = hello
+
+class hello_failed_error_msg(error_msg):
+    version = 1
+    type = 1
+    err_type = 0
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 0)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[0] = hello_failed_error_msg
+
+class nicira_header(experimenter):
+    subtypes = {}
+
+    version = 1
+    type = 4
+    experimenter = 8992
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = nicira_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira_header
+
+class nicira_controller_role_reply(nicira_header):
+    version = 1
+    type = 4
+    experimenter = 8992
+    subtype = 11
+
+    def __init__(self, xid=None, role=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.role))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_controller_role_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.role = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_controller_role_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+            q.breakable()
+        q.text('}')
+
+nicira_header.subtypes[11] = nicira_controller_role_reply
+
+class nicira_controller_role_request(nicira_header):
+    version = 1
+    type = 4
+    experimenter = 8992
+    subtype = 10
+
+    def __init__(self, xid=None, role=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.role))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_controller_role_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.role = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_controller_role_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+            q.breakable()
+        q.text('}')
+
+nicira_header.subtypes[10] = nicira_controller_role_request
+
+class packet_in(message):
+    version = 1
+    type = 10
+
+    def __init__(self, xid=None, buffer_id=None, total_len=None, in_port=None, reason=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if total_len != None:
+            self.total_len = total_len
+        else:
+            self.total_len = 0
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(struct.pack("!H", self.total_len))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 1)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_in()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.total_len = reader.read("!H")[0]
+        obj.in_port = util.unpack_port_no(reader)
+        obj.reason = reader.read("!B")[0]
+        reader.skip(1)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.total_len != other.total_len: return False
+        if self.in_port != other.in_port: return False
+        if self.reason != other.reason: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("total_len = ");
+                q.text("%#x" % self.total_len)
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[10] = packet_in
+
+class packet_out(message):
+    version = 1
+    type = 13
+
+    def __init__(self, xid=None, buffer_id=None, in_port=None, actions=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(struct.pack("!H", 0)) # placeholder for actions_len at index 6
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        packed[6] = struct.pack("!H", len(packed[-1]))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_out()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.in_port = util.unpack_port_no(reader)
+        _actions_len = reader.read("!H")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader.slice(_actions_len), ofp.action.action.unpack)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.in_port != other.in_port: return False
+        if self.actions != other.actions: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[13] = packet_out
+
+class port_mod(message):
+    version = 1
+    type = 15
+
+    def __init__(self, xid=None, port_no=None, hw_addr=None, config=None, mask=None, advertise=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        if advertise != None:
+            self.advertise = advertise
+        else:
+            self.advertise = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.mask))
+        packed.append(struct.pack("!L", self.advertise))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.hw_addr = list(reader.read('!6B'))
+        obj.config = reader.read("!L")[0]
+        obj.mask = reader.read("!L")[0]
+        obj.advertise = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.config != other.config: return False
+        if self.mask != other.mask: return False
+        if self.advertise != other.advertise: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+                q.text(","); q.breakable()
+                q.text("advertise = ");
+                q.text("%#x" % self.advertise)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[15] = port_mod
+
+class port_mod_failed_error_msg(error_msg):
+    version = 1
+    type = 1
+    err_type = 4
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 4)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[4] = port_mod_failed_error_msg
+
+class port_stats_reply(stats_reply):
+    version = 1
+    type = 17
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.port_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[4] = port_stats_reply
+
+class port_stats_request(stats_request):
+    version = 1
+    type = 16
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[4] = port_stats_request
+
+class port_status(message):
+    version = 1
+    type = 12
+
+    def __init__(self, xid=None, reason=None, desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if desc != None:
+            self.desc = desc
+        else:
+            self.desc = ofp.port_desc()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 7)
+        packed.append(self.desc.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(7)
+        obj.desc = ofp.port_desc.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.reason != other.reason: return False
+        if self.desc != other.desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("desc = ");
+                q.pp(self.desc)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[12] = port_status
+
+class queue_get_config_reply(message):
+    version = 1
+    type = 21
+
+    def __init__(self, xid=None, port=None, queues=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if queues != None:
+            self.queues = queues
+        else:
+            self.queues = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.queues))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 21)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(6)
+        obj.queues = loxi.generic_util.unpack_list(reader, ofp.common.packet_queue.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        if self.queues != other.queues: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("queues = ");
+                q.pp(self.queues)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[21] = queue_get_config_reply
+
+class queue_get_config_request(message):
+    version = 1
+    type = 20
+
+    def __init__(self, xid=None, port=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 20)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+            q.breakable()
+        q.text('}')
+
+message.subtypes[20] = queue_get_config_request
+
+class queue_op_failed_error_msg(error_msg):
+    version = 1
+    type = 1
+    err_type = 5
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_op_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 5)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_op_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[5] = queue_op_failed_error_msg
+
+class queue_stats_reply(stats_reply):
+    version = 1
+    type = 17
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.queue_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[5] = queue_stats_reply
+
+class queue_stats_request(stats_request):
+    version = 1
+    type = 16
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, port_no=None, queue_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(2)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[5] = queue_stats_request
+
+class set_config(message):
+    version = 1
+    type = 9
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_config()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_config {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[9] = set_config
+
+class table_mod(message):
+    version = 1
+    type = 22
+
+    def __init__(self, xid=None, table_id=None, config=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.config))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 22)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.config = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.config != other.config: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[22] = table_mod
+
+class table_stats_reply(stats_reply):
+    version = 1
+    type = 17
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[3] = table_stats_reply
+
+class table_stats_request(stats_request):
+    version = 1
+    type = 16
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[3] = table_stats_request
+
+
+def parse_header(buf):
+    if len(buf) < 8:
+        raise loxi.ProtocolError("too short to be an OpenFlow message")
+    return struct.unpack_from("!BBHL", buf)
+
+def parse_message(buf):
+    msg_ver, msg_type, msg_len, msg_xid = parse_header(buf)
+    if msg_ver != ofp.OFP_VERSION and msg_type != ofp.OFPT_HELLO:
+        raise loxi.ProtocolError("wrong OpenFlow version (expected %d, got %d)" % (ofp.OFP_VERSION, msg_ver))
+    if len(buf) != msg_len:
+        raise loxi.ProtocolError("incorrect message size")
+    return message.unpack(loxi.generic_util.OFReader(buf))
diff --git a/Fabric/Utilities/src/python/loxi/of10/util.py b/Fabric/Utilities/src/python/loxi/of10/util.py
new file mode 100644
index 0000000..2e68b0b
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of10/util.py
@@ -0,0 +1,142 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+# Automatically generated by LOXI from template util.py
+# Do not modify
+
+import struct
+import loxi
+import const
+import common
+import action
+
+def pretty_mac(mac):
+    return ':'.join(["%02x" % x for x in mac])
+
+def pretty_ipv4(v):
+    return "%d.%d.%d.%d" % ((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF)
+
+def pretty_flags(v, flag_names):
+    set_flags = []
+    for flag_name in flag_names:
+        flag_value = getattr(const, flag_name)
+        if v & flag_value == flag_value:
+            set_flags.append(flag_name)
+        elif v & flag_value:
+            set_flags.append('%s&%#x' % (flag_name, v & flag_value))
+        v &= ~flag_value
+    if v:
+        set_flags.append("%#x" % v)
+    return '|'.join(set_flags) or '0'
+
+def pretty_wildcards(v):
+    if v == const.OFPFW_ALL:
+        return 'OFPFW_ALL'
+    flag_names = ['OFPFW_IN_PORT', 'OFPFW_DL_VLAN', 'OFPFW_DL_SRC', 'OFPFW_DL_DST',
+                  'OFPFW_DL_TYPE', 'OFPFW_NW_PROTO', 'OFPFW_TP_SRC', 'OFPFW_TP_DST',
+                  'OFPFW_NW_SRC_MASK', 'OFPFW_NW_DST_MASK', 'OFPFW_DL_VLAN_PCP',
+                  'OFPFW_NW_TOS']
+    return pretty_flags(v, flag_names)
+
+def pretty_port(v):
+    named_ports = [(k,v2) for (k,v2) in const.__dict__.iteritems() if k.startswith('OFPP_')]
+    for (k, v2) in named_ports:
+        if v == v2:
+            return k
+    return v
+
+def pack_port_no(value):
+    return struct.pack("!H", value)
+
+def unpack_port_no(reader):
+    return reader.read("!H")[0]
+
+def pack_fm_cmd(value):
+    return struct.pack("!H", value)
+
+def unpack_fm_cmd(reader):
+    return reader.read("!H")[0]
+
+def init_wc_bmap():
+    return const.OFPFW_ALL
+
+def pack_wc_bmap(value):
+    return struct.pack("!L", value)
+
+def unpack_wc_bmap(reader):
+    return reader.read("!L")[0]
+
+def init_match_bmap():
+    return const.OFPFW_ALL
+
+def pack_match_bmap(value):
+    return struct.pack("!L", value)
+
+def unpack_match_bmap(reader):
+    return reader.read("!L")[0]
+
+MASK64 = (1 << 64) - 1
+
+def pack_bitmap_128(value):
+    x = 0l
+    for y in value:
+        x |= 1 << y
+    return struct.pack("!QQ", (x >> 64) & MASK64, x & MASK64)
+
+def unpack_bitmap_128(reader):
+    hi, lo = reader.read("!QQ")
+    x = (hi << 64) | lo
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_bitmap_512(value):
+    words = [0] * 8
+    for v in value:
+        assert v < 512
+        words[7-v/64] |= 1 << (v % 64)
+    return struct.pack("!8Q", *words)
+
+def unpack_bitmap_512(reader):
+    words = reader.read("!8Q")
+    x = 0l
+    for word in words:
+        x <<= 64
+        x |= word
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_checksum_128(value):
+    return struct.pack("!QQ", (value >> 64) & MASK64, value & MASK64)
+
+def unpack_checksum_128(reader):
+    hi, lo = reader.read("!QQ")
+    return (hi << 64) | lo
diff --git a/Fabric/Utilities/src/python/loxi/of11/__init__.py b/Fabric/Utilities/src/python/loxi/of11/__init__.py
new file mode 100644
index 0000000..605c1fb
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of11/__init__.py
@@ -0,0 +1,32 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template init.py
+# Do not modify
+
+import const
+import action
+import message
+import instruction
+import common
+from const import *
+from common import *
+from loxi import ProtocolError
diff --git a/Fabric/Utilities/src/python/loxi/of11/action.py b/Fabric/Utilities/src/python/loxi/of11/action.py
new file mode 100644
index 0000000..3ad2c90
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of11/action.py
@@ -0,0 +1,1678 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of11']
+
+class action(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = action.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = action()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("action {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(action):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_checksum(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_checksum_128(self.checksum))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_checksum()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_checksum {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_checksum
+
+class bsn_mirror(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, dest_port=None, vlan_tag=None, copy_stage=None):
+        if dest_port != None:
+            self.dest_port = dest_port
+        else:
+            self.dest_port = 0
+        if vlan_tag != None:
+            self.vlan_tag = vlan_tag
+        else:
+            self.vlan_tag = 0
+        if copy_stage != None:
+            self.copy_stage = copy_stage
+        else:
+            self.copy_stage = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dest_port))
+        packed.append(struct.pack("!L", self.vlan_tag))
+        packed.append(struct.pack("!B", self.copy_stage))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_mirror()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.dest_port = reader.read("!L")[0]
+        obj.vlan_tag = reader.read("!L")[0]
+        obj.copy_stage = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dest_port != other.dest_port: return False
+        if self.vlan_tag != other.vlan_tag: return False
+        if self.copy_stage != other.copy_stage: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_mirror {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dest_port = ");
+                q.text("%#x" % self.dest_port)
+                q.text(","); q.breakable()
+                q.text("vlan_tag = ");
+                q.text("%#x" % self.vlan_tag)
+                q.text(","); q.breakable()
+                q.text("copy_stage = ");
+                q.text("%#x" % self.copy_stage)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_mirror
+
+class bsn_set_tunnel_dst(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, dst=None):
+        if dst != None:
+            self.dst = dst
+        else:
+            self.dst = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dst))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_tunnel_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.dst = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dst != other.dst: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_tunnel_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dst = ");
+                q.text("%#x" % self.dst)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_set_tunnel_dst
+
+class copy_ttl_in(action):
+    type = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_in()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[12] = copy_ttl_in
+
+class copy_ttl_out(action):
+    type = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_out()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[11] = copy_ttl_out
+
+class dec_mpls_ttl(action):
+    type = 16
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[16] = dec_mpls_ttl
+
+class dec_nw_ttl(action):
+    type = 24
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[24] = dec_nw_ttl
+
+class group(action):
+    type = 22
+
+    def __init__(self, group_id=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.group_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.group_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[22] = group
+
+class nicira(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 8992
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = nicira.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!H")[0]
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira
+
+class nicira_dec_ttl(nicira):
+    type = 65535
+    experimenter = 8992
+    subtype = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_dec_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == 18)
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_dec_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+nicira.subtypes[18] = nicira_dec_ttl
+
+class output(action):
+    type = 0
+
+    def __init__(self, port=None, max_len=None):
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if max_len != None:
+            self.max_len = max_len
+        else:
+            self.max_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", self.max_len))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = output()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.port = util.unpack_port_no(reader)
+        obj.max_len = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port != other.port: return False
+        if self.max_len != other.max_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("max_len = ");
+                q.text("%#x" % self.max_len)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[0] = output
+
+class pop_mpls(action):
+    type = 20
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[20] = pop_mpls
+
+class pop_vlan(action):
+    type = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[18] = pop_vlan
+
+class push_mpls(action):
+    type = 19
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[19] = push_mpls
+
+class push_vlan(action):
+    type = 17
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[17] = push_vlan
+
+class set_dl_dst(action):
+    type = 4
+
+    def __init__(self, dl_addr=None):
+        if dl_addr != None:
+            self.dl_addr = dl_addr
+        else:
+            self.dl_addr = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!6B", *self.dl_addr))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_dl_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.dl_addr = list(reader.read('!6B'))
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dl_addr != other.dl_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_dl_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dl_addr = ");
+                q.text(util.pretty_mac(self.dl_addr))
+            q.breakable()
+        q.text('}')
+
+action.subtypes[4] = set_dl_dst
+
+class set_dl_src(action):
+    type = 3
+
+    def __init__(self, dl_addr=None):
+        if dl_addr != None:
+            self.dl_addr = dl_addr
+        else:
+            self.dl_addr = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!6B", *self.dl_addr))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_dl_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.dl_addr = list(reader.read('!6B'))
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dl_addr != other.dl_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_dl_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dl_addr = ");
+                q.text(util.pretty_mac(self.dl_addr))
+            q.breakable()
+        q.text('}')
+
+action.subtypes[3] = set_dl_src
+
+class set_mpls_label(action):
+    type = 13
+
+    def __init__(self, mpls_label=None):
+        if mpls_label != None:
+            self.mpls_label = mpls_label
+        else:
+            self.mpls_label = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.mpls_label))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_label()
+        _type = reader.read("!H")[0]
+        assert(_type == 13)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.mpls_label = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mpls_label != other.mpls_label: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_label {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mpls_label = ");
+                q.text("%#x" % self.mpls_label)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[13] = set_mpls_label
+
+class set_mpls_tc(action):
+    type = 14
+
+    def __init__(self, mpls_tc=None):
+        if mpls_tc != None:
+            self.mpls_tc = mpls_tc
+        else:
+            self.mpls_tc = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.mpls_tc))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_tc()
+        _type = reader.read("!H")[0]
+        assert(_type == 14)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.mpls_tc = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mpls_tc != other.mpls_tc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_tc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mpls_tc = ");
+                q.text("%#x" % self.mpls_tc)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[14] = set_mpls_tc
+
+class set_mpls_ttl(action):
+    type = 15
+
+    def __init__(self, mpls_ttl=None):
+        if mpls_ttl != None:
+            self.mpls_ttl = mpls_ttl
+        else:
+            self.mpls_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.mpls_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.mpls_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mpls_ttl != other.mpls_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mpls_ttl = ");
+                q.text("%#x" % self.mpls_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[15] = set_mpls_ttl
+
+class set_nw_dst(action):
+    type = 6
+
+    def __init__(self, nw_addr=None):
+        if nw_addr != None:
+            self.nw_addr = nw_addr
+        else:
+            self.nw_addr = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.nw_addr))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_addr = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_addr != other.nw_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_addr = ");
+                q.text("%#x" % self.nw_addr)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[6] = set_nw_dst
+
+class set_nw_ecn(action):
+    type = 8
+
+    def __init__(self, nw_ecn=None):
+        if nw_ecn != None:
+            self.nw_ecn = nw_ecn
+        else:
+            self.nw_ecn = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.nw_ecn))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_ecn()
+        _type = reader.read("!H")[0]
+        assert(_type == 8)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_ecn = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_ecn != other.nw_ecn: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_ecn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_ecn = ");
+                q.text("%#x" % self.nw_ecn)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[8] = set_nw_ecn
+
+class set_nw_src(action):
+    type = 5
+
+    def __init__(self, nw_addr=None):
+        if nw_addr != None:
+            self.nw_addr = nw_addr
+        else:
+            self.nw_addr = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.nw_addr))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_addr = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_addr != other.nw_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_addr = ");
+                q.text("%#x" % self.nw_addr)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[5] = set_nw_src
+
+class set_nw_tos(action):
+    type = 7
+
+    def __init__(self, nw_tos=None):
+        if nw_tos != None:
+            self.nw_tos = nw_tos
+        else:
+            self.nw_tos = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.nw_tos))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_tos()
+        _type = reader.read("!H")[0]
+        assert(_type == 7)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_tos = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_tos != other.nw_tos: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_tos {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_tos = ");
+                q.text("%#x" % self.nw_tos)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[7] = set_nw_tos
+
+class set_nw_ttl(action):
+    type = 23
+
+    def __init__(self, nw_ttl=None):
+        if nw_ttl != None:
+            self.nw_ttl = nw_ttl
+        else:
+            self.nw_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.nw_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_ttl != other.nw_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_ttl = ");
+                q.text("%#x" % self.nw_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[23] = set_nw_ttl
+
+class set_queue(action):
+    type = 21
+
+    def __init__(self, queue_id=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_queue()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[21] = set_queue
+
+class set_tp_dst(action):
+    type = 10
+
+    def __init__(self, tp_port=None):
+        if tp_port != None:
+            self.tp_port = tp_port
+        else:
+            self.tp_port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.tp_port))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_tp_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 10)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.tp_port = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.tp_port != other.tp_port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_tp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("tp_port = ");
+                q.text("%#x" % self.tp_port)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[10] = set_tp_dst
+
+class set_tp_src(action):
+    type = 9
+
+    def __init__(self, tp_port=None):
+        if tp_port != None:
+            self.tp_port = tp_port
+        else:
+            self.tp_port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.tp_port))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_tp_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 9)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.tp_port = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.tp_port != other.tp_port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_tp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("tp_port = ");
+                q.text("%#x" % self.tp_port)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[9] = set_tp_src
+
+class set_vlan_pcp(action):
+    type = 2
+
+    def __init__(self, vlan_pcp=None):
+        if vlan_pcp != None:
+            self.vlan_pcp = vlan_pcp
+        else:
+            self.vlan_pcp = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.vlan_pcp))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_vlan_pcp()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.vlan_pcp = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vlan_pcp != other.vlan_pcp: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_vlan_pcp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vlan_pcp = ");
+                q.text("%#x" % self.vlan_pcp)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[2] = set_vlan_pcp
+
+class set_vlan_vid(action):
+    type = 1
+
+    def __init__(self, vlan_vid=None):
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_vlan_vid()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.vlan_vid = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vlan_vid != other.vlan_vid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[1] = set_vlan_vid
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of11/common.py b/Fabric/Utilities/src/python/loxi/of11/common.py
new file mode 100644
index 0000000..2ca0cba
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of11/common.py
@@ -0,0 +1,1747 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of11']
+
+class bsn_interface(loxi.OFObject):
+
+    def __init__(self, hw_addr=None, name=None, ipv4_addr=None, ipv4_netmask=None):
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if ipv4_addr != None:
+            self.ipv4_addr = ipv4_addr
+        else:
+            self.ipv4_addr = 0
+        if ipv4_netmask != None:
+            self.ipv4_netmask = ipv4_netmask
+        else:
+            self.ipv4_netmask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.ipv4_addr))
+        packed.append(struct.pack("!L", self.ipv4_netmask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_interface()
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.ipv4_addr = reader.read("!L")[0]
+        obj.ipv4_netmask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.ipv4_addr != other.ipv4_addr: return False
+        if self.ipv4_netmask != other.ipv4_netmask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_interface {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("ipv4_addr = ");
+                q.text(util.pretty_ipv4(self.ipv4_addr))
+                q.text(","); q.breakable()
+                q.text("ipv4_netmask = ");
+                q.text(util.pretty_ipv4(self.ipv4_netmask))
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bsn_vport.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_vport()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport_l2gre(bsn_vport):
+    type = 1
+
+    def __init__(self, flags=None, port_no=None, loopback_port_no=None, local_mac=None, nh_mac=None, src_ip=None, dst_ip=None, dscp=None, ttl=None, vpn=None, rate_limit=None, if_name=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if loopback_port_no != None:
+            self.loopback_port_no = loopback_port_no
+        else:
+            self.loopback_port_no = 0
+        if local_mac != None:
+            self.local_mac = local_mac
+        else:
+            self.local_mac = [0,0,0,0,0,0]
+        if nh_mac != None:
+            self.nh_mac = nh_mac
+        else:
+            self.nh_mac = [0,0,0,0,0,0]
+        if src_ip != None:
+            self.src_ip = src_ip
+        else:
+            self.src_ip = 0
+        if dst_ip != None:
+            self.dst_ip = dst_ip
+        else:
+            self.dst_ip = 0
+        if dscp != None:
+            self.dscp = dscp
+        else:
+            self.dscp = 0
+        if ttl != None:
+            self.ttl = ttl
+        else:
+            self.ttl = 0
+        if vpn != None:
+            self.vpn = vpn
+        else:
+            self.vpn = 0
+        if rate_limit != None:
+            self.rate_limit = rate_limit
+        else:
+            self.rate_limit = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.flags))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(util.pack_port_no(self.loopback_port_no))
+        packed.append(struct.pack("!6B", *self.local_mac))
+        packed.append(struct.pack("!6B", *self.nh_mac))
+        packed.append(struct.pack("!L", self.src_ip))
+        packed.append(struct.pack("!L", self.dst_ip))
+        packed.append(struct.pack("!B", self.dscp))
+        packed.append(struct.pack("!B", self.ttl))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.vpn))
+        packed.append(struct.pack("!L", self.rate_limit))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_l2gre()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.flags = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.loopback_port_no = util.unpack_port_no(reader)
+        obj.local_mac = list(reader.read('!6B'))
+        obj.nh_mac = list(reader.read('!6B'))
+        obj.src_ip = reader.read("!L")[0]
+        obj.dst_ip = reader.read("!L")[0]
+        obj.dscp = reader.read("!B")[0]
+        obj.ttl = reader.read("!B")[0]
+        reader.skip(2)
+        obj.vpn = reader.read("!L")[0]
+        obj.rate_limit = reader.read("!L")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.loopback_port_no != other.loopback_port_no: return False
+        if self.local_mac != other.local_mac: return False
+        if self.nh_mac != other.nh_mac: return False
+        if self.src_ip != other.src_ip: return False
+        if self.dst_ip != other.dst_ip: return False
+        if self.dscp != other.dscp: return False
+        if self.ttl != other.ttl: return False
+        if self.vpn != other.vpn: return False
+        if self.rate_limit != other.rate_limit: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_l2gre {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("loopback_port_no = ");
+                q.text(util.pretty_port(self.loopback_port_no))
+                q.text(","); q.breakable()
+                q.text("local_mac = ");
+                q.text(util.pretty_mac(self.local_mac))
+                q.text(","); q.breakable()
+                q.text("nh_mac = ");
+                q.text(util.pretty_mac(self.nh_mac))
+                q.text(","); q.breakable()
+                q.text("src_ip = ");
+                q.text(util.pretty_ipv4(self.src_ip))
+                q.text(","); q.breakable()
+                q.text("dst_ip = ");
+                q.text(util.pretty_ipv4(self.dst_ip))
+                q.text(","); q.breakable()
+                q.text("dscp = ");
+                q.text("%#x" % self.dscp)
+                q.text(","); q.breakable()
+                q.text("ttl = ");
+                q.text("%#x" % self.ttl)
+                q.text(","); q.breakable()
+                q.text("vpn = ");
+                q.text("%#x" % self.vpn)
+                q.text(","); q.breakable()
+                q.text("rate_limit = ");
+                q.text("%#x" % self.rate_limit)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[1] = bsn_vport_l2gre
+
+class bsn_vport_q_in_q(bsn_vport):
+    type = 0
+
+    def __init__(self, port_no=None, ingress_tpid=None, ingress_vlan_id=None, egress_tpid=None, egress_vlan_id=None, if_name=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if ingress_tpid != None:
+            self.ingress_tpid = ingress_tpid
+        else:
+            self.ingress_tpid = 0
+        if ingress_vlan_id != None:
+            self.ingress_vlan_id = ingress_vlan_id
+        else:
+            self.ingress_vlan_id = 0
+        if egress_tpid != None:
+            self.egress_tpid = egress_tpid
+        else:
+            self.egress_tpid = 0
+        if egress_vlan_id != None:
+            self.egress_vlan_id = egress_vlan_id
+        else:
+            self.egress_vlan_id = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.port_no))
+        packed.append(struct.pack("!H", self.ingress_tpid))
+        packed.append(struct.pack("!H", self.ingress_vlan_id))
+        packed.append(struct.pack("!H", self.egress_tpid))
+        packed.append(struct.pack("!H", self.egress_vlan_id))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_q_in_q()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.port_no = reader.read("!L")[0]
+        obj.ingress_tpid = reader.read("!H")[0]
+        obj.ingress_vlan_id = reader.read("!H")[0]
+        obj.egress_tpid = reader.read("!H")[0]
+        obj.egress_vlan_id = reader.read("!H")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.ingress_tpid != other.ingress_tpid: return False
+        if self.ingress_vlan_id != other.ingress_vlan_id: return False
+        if self.egress_tpid != other.egress_tpid: return False
+        if self.egress_vlan_id != other.egress_vlan_id: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_q_in_q {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text("%#x" % self.port_no)
+                q.text(","); q.breakable()
+                q.text("ingress_tpid = ");
+                q.text("%#x" % self.ingress_tpid)
+                q.text(","); q.breakable()
+                q.text("ingress_vlan_id = ");
+                q.text("%#x" % self.ingress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("egress_tpid = ");
+                q.text("%#x" % self.egress_tpid)
+                q.text(","); q.breakable()
+                q.text("egress_vlan_id = ");
+                q.text("%#x" % self.egress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[0] = bsn_vport_q_in_q
+
+class bucket(loxi.OFObject):
+
+    def __init__(self, weight=None, watch_port=None, watch_group=None, actions=None):
+        if weight != None:
+            self.weight = weight
+        else:
+            self.weight = 0
+        if watch_port != None:
+            self.watch_port = watch_port
+        else:
+            self.watch_port = 0
+        if watch_group != None:
+            self.watch_group = watch_group
+        else:
+            self.watch_group = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 0
+        packed.append(struct.pack("!H", self.weight))
+        packed.append(util.pack_port_no(self.watch_port))
+        packed.append(struct.pack("!L", self.watch_group))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket()
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 2)
+        obj.weight = reader.read("!H")[0]
+        obj.watch_port = util.unpack_port_no(reader)
+        obj.watch_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.weight != other.weight: return False
+        if self.watch_port != other.watch_port: return False
+        if self.watch_group != other.watch_group: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("weight = ");
+                q.text("%#x" % self.weight)
+                q.text(","); q.breakable()
+                q.text("watch_port = ");
+                q.text(util.pretty_port(self.watch_port))
+                q.text(","); q.breakable()
+                q.text("watch_group = ");
+                q.text("%#x" % self.watch_group)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+
+class bucket_counter(loxi.OFObject):
+
+    def __init__(self, packet_count=None, byte_count=None):
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket_counter()
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket_counter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+            q.breakable()
+        q.text('}')
+
+
+class flow_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, duration_sec=None, duration_nsec=None, priority=None, idle_timeout=None, hard_timeout=None, cookie=None, packet_count=None, byte_count=None, match=None, instructions=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append('\x00' * 6)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        reader.skip(6)
+        obj.cookie = reader.read("!Q")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.priority != other.priority: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.cookie != other.cookie: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+
+class group_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_type=None, group_id=None, buckets=None):
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+
+class group_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_id=None, ref_count=None, packet_count=None, byte_count=None, bucket_stats=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if ref_count != None:
+            self.ref_count = ref_count
+        else:
+            self.ref_count = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if bucket_stats != None:
+            self.bucket_stats = bucket_stats
+        else:
+            self.bucket_stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(struct.pack("!L", self.ref_count))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(loxi.generic_util.pack_list(self.bucket_stats))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.group_id = reader.read("!L")[0]
+        obj.ref_count = reader.read("!L")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.bucket_stats = loxi.generic_util.unpack_list(reader, ofp.common.bucket_counter.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        if self.ref_count != other.ref_count: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.bucket_stats != other.bucket_stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("ref_count = ");
+                q.text("%#x" % self.ref_count)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("bucket_stats = ");
+                q.pp(self.bucket_stats)
+            q.breakable()
+        q.text('}')
+
+
+class match_v2(loxi.OFObject):
+    type = 0
+
+    def __init__(self, in_port=None, wildcards=None, eth_src=None, eth_src_mask=None, eth_dst=None, eth_dst_mask=None, vlan_vid=None, vlan_pcp=None, eth_type=None, ip_dscp=None, ip_proto=None, ipv4_src=None, ipv4_src_mask=None, ipv4_dst=None, ipv4_dst_mask=None, tcp_src=None, tcp_dst=None, mpls_label=None, mpls_tc=None, metadata=None, metadata_mask=None):
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if wildcards != None:
+            self.wildcards = wildcards
+        else:
+            self.wildcards = util.init_wc_bmap()
+        if eth_src != None:
+            self.eth_src = eth_src
+        else:
+            self.eth_src = [0,0,0,0,0,0]
+        if eth_src_mask != None:
+            self.eth_src_mask = eth_src_mask
+        else:
+            self.eth_src_mask = [0,0,0,0,0,0]
+        if eth_dst != None:
+            self.eth_dst = eth_dst
+        else:
+            self.eth_dst = [0,0,0,0,0,0]
+        if eth_dst_mask != None:
+            self.eth_dst_mask = eth_dst_mask
+        else:
+            self.eth_dst_mask = [0,0,0,0,0,0]
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        if vlan_pcp != None:
+            self.vlan_pcp = vlan_pcp
+        else:
+            self.vlan_pcp = 0
+        if eth_type != None:
+            self.eth_type = eth_type
+        else:
+            self.eth_type = 0
+        if ip_dscp != None:
+            self.ip_dscp = ip_dscp
+        else:
+            self.ip_dscp = 0
+        if ip_proto != None:
+            self.ip_proto = ip_proto
+        else:
+            self.ip_proto = 0
+        if ipv4_src != None:
+            self.ipv4_src = ipv4_src
+        else:
+            self.ipv4_src = 0
+        if ipv4_src_mask != None:
+            self.ipv4_src_mask = ipv4_src_mask
+        else:
+            self.ipv4_src_mask = 0
+        if ipv4_dst != None:
+            self.ipv4_dst = ipv4_dst
+        else:
+            self.ipv4_dst = 0
+        if ipv4_dst_mask != None:
+            self.ipv4_dst_mask = ipv4_dst_mask
+        else:
+            self.ipv4_dst_mask = 0
+        if tcp_src != None:
+            self.tcp_src = tcp_src
+        else:
+            self.tcp_src = 0
+        if tcp_dst != None:
+            self.tcp_dst = tcp_dst
+        else:
+            self.tcp_dst = 0
+        if mpls_label != None:
+            self.mpls_label = mpls_label
+        else:
+            self.mpls_label = 0
+        if mpls_tc != None:
+            self.mpls_tc = mpls_tc
+        else:
+            self.mpls_tc = 0
+        if metadata != None:
+            self.metadata = metadata
+        else:
+            self.metadata = 0
+        if metadata_mask != None:
+            self.metadata_mask = metadata_mask
+        else:
+            self.metadata_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(util.pack_wc_bmap(self.wildcards))
+        packed.append(struct.pack("!6B", *self.eth_src))
+        packed.append(struct.pack("!6B", *self.eth_src_mask))
+        packed.append(struct.pack("!6B", *self.eth_dst))
+        packed.append(struct.pack("!6B", *self.eth_dst_mask))
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append(struct.pack("!B", self.vlan_pcp))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.eth_type))
+        packed.append(struct.pack("!B", self.ip_dscp))
+        packed.append(struct.pack("!B", self.ip_proto))
+        packed.append(struct.pack("!L", self.ipv4_src))
+        packed.append(struct.pack("!L", self.ipv4_src_mask))
+        packed.append(struct.pack("!L", self.ipv4_dst))
+        packed.append(struct.pack("!L", self.ipv4_dst_mask))
+        packed.append(struct.pack("!H", self.tcp_src))
+        packed.append(struct.pack("!H", self.tcp_dst))
+        packed.append(struct.pack("!L", self.mpls_label))
+        packed.append(struct.pack("!B", self.mpls_tc))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!Q", self.metadata))
+        packed.append(struct.pack("!Q", self.metadata_mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = match_v2()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.in_port = util.unpack_port_no(reader)
+        obj.wildcards = util.unpack_wc_bmap(reader)
+        obj.eth_src = list(reader.read('!6B'))
+        obj.eth_src_mask = list(reader.read('!6B'))
+        obj.eth_dst = list(reader.read('!6B'))
+        obj.eth_dst_mask = list(reader.read('!6B'))
+        obj.vlan_vid = reader.read("!H")[0]
+        obj.vlan_pcp = reader.read("!B")[0]
+        reader.skip(1)
+        obj.eth_type = reader.read("!H")[0]
+        obj.ip_dscp = reader.read("!B")[0]
+        obj.ip_proto = reader.read("!B")[0]
+        obj.ipv4_src = reader.read("!L")[0]
+        obj.ipv4_src_mask = reader.read("!L")[0]
+        obj.ipv4_dst = reader.read("!L")[0]
+        obj.ipv4_dst_mask = reader.read("!L")[0]
+        obj.tcp_src = reader.read("!H")[0]
+        obj.tcp_dst = reader.read("!H")[0]
+        obj.mpls_label = reader.read("!L")[0]
+        obj.mpls_tc = reader.read("!B")[0]
+        reader.skip(3)
+        obj.metadata = reader.read("!Q")[0]
+        obj.metadata_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.in_port != other.in_port: return False
+        if self.wildcards != other.wildcards: return False
+        if self.eth_src != other.eth_src: return False
+        if self.eth_src_mask != other.eth_src_mask: return False
+        if self.eth_dst != other.eth_dst: return False
+        if self.eth_dst_mask != other.eth_dst_mask: return False
+        if self.vlan_vid != other.vlan_vid: return False
+        if self.vlan_pcp != other.vlan_pcp: return False
+        if self.eth_type != other.eth_type: return False
+        if self.ip_dscp != other.ip_dscp: return False
+        if self.ip_proto != other.ip_proto: return False
+        if self.ipv4_src != other.ipv4_src: return False
+        if self.ipv4_src_mask != other.ipv4_src_mask: return False
+        if self.ipv4_dst != other.ipv4_dst: return False
+        if self.ipv4_dst_mask != other.ipv4_dst_mask: return False
+        if self.tcp_src != other.tcp_src: return False
+        if self.tcp_dst != other.tcp_dst: return False
+        if self.mpls_label != other.mpls_label: return False
+        if self.mpls_tc != other.mpls_tc: return False
+        if self.metadata != other.metadata: return False
+        if self.metadata_mask != other.metadata_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("match_v2 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("wildcards = ");
+                q.text(util.pretty_wildcards(self.wildcards))
+                q.text(","); q.breakable()
+                q.text("eth_src = ");
+                q.text(util.pretty_mac(self.eth_src))
+                q.text(","); q.breakable()
+                q.text("eth_src_mask = ");
+                q.text(util.pretty_mac(self.eth_src_mask))
+                q.text(","); q.breakable()
+                q.text("eth_dst = ");
+                q.text(util.pretty_mac(self.eth_dst))
+                q.text(","); q.breakable()
+                q.text("eth_dst_mask = ");
+                q.text(util.pretty_mac(self.eth_dst_mask))
+                q.text(","); q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+                q.text(","); q.breakable()
+                q.text("vlan_pcp = ");
+                q.text("%#x" % self.vlan_pcp)
+                q.text(","); q.breakable()
+                q.text("eth_type = ");
+                q.text("%#x" % self.eth_type)
+                q.text(","); q.breakable()
+                q.text("ip_dscp = ");
+                q.text("%#x" % self.ip_dscp)
+                q.text(","); q.breakable()
+                q.text("ip_proto = ");
+                q.text("%#x" % self.ip_proto)
+                q.text(","); q.breakable()
+                q.text("ipv4_src = ");
+                q.text(util.pretty_ipv4(self.ipv4_src))
+                q.text(","); q.breakable()
+                q.text("ipv4_src_mask = ");
+                q.text(util.pretty_ipv4(self.ipv4_src_mask))
+                q.text(","); q.breakable()
+                q.text("ipv4_dst = ");
+                q.text(util.pretty_ipv4(self.ipv4_dst))
+                q.text(","); q.breakable()
+                q.text("ipv4_dst_mask = ");
+                q.text(util.pretty_ipv4(self.ipv4_dst_mask))
+                q.text(","); q.breakable()
+                q.text("tcp_src = ");
+                q.text("%#x" % self.tcp_src)
+                q.text(","); q.breakable()
+                q.text("tcp_dst = ");
+                q.text("%#x" % self.tcp_dst)
+                q.text(","); q.breakable()
+                q.text("mpls_label = ");
+                q.text("%#x" % self.mpls_label)
+                q.text(","); q.breakable()
+                q.text("mpls_tc = ");
+                q.text("%#x" % self.mpls_tc)
+                q.text(","); q.breakable()
+                q.text("metadata = ");
+                q.text("%#x" % self.metadata)
+                q.text(","); q.breakable()
+                q.text("metadata_mask = ");
+                q.text("%#x" % self.metadata_mask)
+            q.breakable()
+        q.text('}')
+
+
+class packet_queue(loxi.OFObject):
+
+    def __init__(self, queue_id=None, properties=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 2)
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_queue()
+        obj.queue_id = reader.read("!L")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 6)
+        reader.skip(2)
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.common.queue_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class port_desc(loxi.OFObject):
+
+    def __init__(self, port_no=None, hw_addr=None, name=None, config=None, state=None, curr=None, advertised=None, supported=None, peer=None, curr_speed=None, max_speed=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if state != None:
+            self.state = state
+        else:
+            self.state = 0
+        if curr != None:
+            self.curr = curr
+        else:
+            self.curr = 0
+        if advertised != None:
+            self.advertised = advertised
+        else:
+            self.advertised = 0
+        if supported != None:
+            self.supported = supported
+        else:
+            self.supported = 0
+        if peer != None:
+            self.peer = peer
+        else:
+            self.peer = 0
+        if curr_speed != None:
+            self.curr_speed = curr_speed
+        else:
+            self.curr_speed = 0
+        if max_speed != None:
+            self.max_speed = max_speed
+        else:
+            self.max_speed = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.state))
+        packed.append(struct.pack("!L", self.curr))
+        packed.append(struct.pack("!L", self.advertised))
+        packed.append(struct.pack("!L", self.supported))
+        packed.append(struct.pack("!L", self.peer))
+        packed.append(struct.pack("!L", self.curr_speed))
+        packed.append(struct.pack("!L", self.max_speed))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.config = reader.read("!L")[0]
+        obj.state = reader.read("!L")[0]
+        obj.curr = reader.read("!L")[0]
+        obj.advertised = reader.read("!L")[0]
+        obj.supported = reader.read("!L")[0]
+        obj.peer = reader.read("!L")[0]
+        obj.curr_speed = reader.read("!L")[0]
+        obj.max_speed = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.config != other.config: return False
+        if self.state != other.state: return False
+        if self.curr != other.curr: return False
+        if self.advertised != other.advertised: return False
+        if self.supported != other.supported: return False
+        if self.peer != other.peer: return False
+        if self.curr_speed != other.curr_speed: return False
+        if self.max_speed != other.max_speed: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("state = ");
+                q.text("%#x" % self.state)
+                q.text(","); q.breakable()
+                q.text("curr = ");
+                q.text("%#x" % self.curr)
+                q.text(","); q.breakable()
+                q.text("advertised = ");
+                q.text("%#x" % self.advertised)
+                q.text(","); q.breakable()
+                q.text("supported = ");
+                q.text("%#x" % self.supported)
+                q.text(","); q.breakable()
+                q.text("peer = ");
+                q.text("%#x" % self.peer)
+                q.text(","); q.breakable()
+                q.text("curr_speed = ");
+                q.text("%#x" % self.curr_speed)
+                q.text(","); q.breakable()
+                q.text("max_speed = ");
+                q.text("%#x" % self.max_speed)
+            q.breakable()
+        q.text('}')
+
+
+class port_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, rx_packets=None, tx_packets=None, rx_bytes=None, tx_bytes=None, rx_dropped=None, tx_dropped=None, rx_errors=None, tx_errors=None, rx_frame_err=None, rx_over_err=None, rx_crc_err=None, collisions=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if rx_packets != None:
+            self.rx_packets = rx_packets
+        else:
+            self.rx_packets = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if rx_bytes != None:
+            self.rx_bytes = rx_bytes
+        else:
+            self.rx_bytes = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if rx_dropped != None:
+            self.rx_dropped = rx_dropped
+        else:
+            self.rx_dropped = 0
+        if tx_dropped != None:
+            self.tx_dropped = tx_dropped
+        else:
+            self.tx_dropped = 0
+        if rx_errors != None:
+            self.rx_errors = rx_errors
+        else:
+            self.rx_errors = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        if rx_frame_err != None:
+            self.rx_frame_err = rx_frame_err
+        else:
+            self.rx_frame_err = 0
+        if rx_over_err != None:
+            self.rx_over_err = rx_over_err
+        else:
+            self.rx_over_err = 0
+        if rx_crc_err != None:
+            self.rx_crc_err = rx_crc_err
+        else:
+            self.rx_crc_err = 0
+        if collisions != None:
+            self.collisions = collisions
+        else:
+            self.collisions = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.rx_packets))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.rx_bytes))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.rx_dropped))
+        packed.append(struct.pack("!Q", self.tx_dropped))
+        packed.append(struct.pack("!Q", self.rx_errors))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        packed.append(struct.pack("!Q", self.rx_frame_err))
+        packed.append(struct.pack("!Q", self.rx_over_err))
+        packed.append(struct.pack("!Q", self.rx_crc_err))
+        packed.append(struct.pack("!Q", self.collisions))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.rx_packets = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.rx_bytes = reader.read("!Q")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.rx_dropped = reader.read("!Q")[0]
+        obj.tx_dropped = reader.read("!Q")[0]
+        obj.rx_errors = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        obj.rx_frame_err = reader.read("!Q")[0]
+        obj.rx_over_err = reader.read("!Q")[0]
+        obj.rx_crc_err = reader.read("!Q")[0]
+        obj.collisions = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.rx_packets != other.rx_packets: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.rx_bytes != other.rx_bytes: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.rx_dropped != other.rx_dropped: return False
+        if self.tx_dropped != other.tx_dropped: return False
+        if self.rx_errors != other.rx_errors: return False
+        if self.tx_errors != other.tx_errors: return False
+        if self.rx_frame_err != other.rx_frame_err: return False
+        if self.rx_over_err != other.rx_over_err: return False
+        if self.rx_crc_err != other.rx_crc_err: return False
+        if self.collisions != other.collisions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("rx_packets = ");
+                q.text("%#x" % self.rx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("rx_bytes = ");
+                q.text("%#x" % self.rx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("rx_dropped = ");
+                q.text("%#x" % self.rx_dropped)
+                q.text(","); q.breakable()
+                q.text("tx_dropped = ");
+                q.text("%#x" % self.tx_dropped)
+                q.text(","); q.breakable()
+                q.text("rx_errors = ");
+                q.text("%#x" % self.rx_errors)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+                q.text(","); q.breakable()
+                q.text("rx_frame_err = ");
+                q.text("%#x" % self.rx_frame_err)
+                q.text(","); q.breakable()
+                q.text("rx_over_err = ");
+                q.text("%#x" % self.rx_over_err)
+                q.text(","); q.breakable()
+                q.text("rx_crc_err = ");
+                q.text("%#x" % self.rx_crc_err)
+                q.text(","); q.breakable()
+                q.text("collisions = ");
+                q.text("%#x" % self.collisions)
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = queue_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop_min_rate(queue_prop):
+    type = 1
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_min_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_min_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[1] = queue_prop_min_rate
+
+class queue_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, queue_id=None, tx_bytes=None, tx_packets=None, tx_errors=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.tx_errors != other.tx_errors: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+            q.breakable()
+        q.text('}')
+
+
+class table_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, name=None, wildcards=None, match=None, instructions=None, write_actions=None, apply_actions=None, config=None, max_entries=None, active_count=None, lookup_count=None, matched_count=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if wildcards != None:
+            self.wildcards = wildcards
+        else:
+            self.wildcards = util.init_wc_bmap()
+        if match != None:
+            self.match = match
+        else:
+            self.match = util.init_match_bmap()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = 0
+        if write_actions != None:
+            self.write_actions = write_actions
+        else:
+            self.write_actions = 0
+        if apply_actions != None:
+            self.apply_actions = apply_actions
+        else:
+            self.apply_actions = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if max_entries != None:
+            self.max_entries = max_entries
+        else:
+            self.max_entries = 0
+        if active_count != None:
+            self.active_count = active_count
+        else:
+            self.active_count = 0
+        if lookup_count != None:
+            self.lookup_count = lookup_count
+        else:
+            self.lookup_count = 0
+        if matched_count != None:
+            self.matched_count = matched_count
+        else:
+            self.matched_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 7)
+        packed.append(struct.pack("!32s", self.name))
+        packed.append(util.pack_wc_bmap(self.wildcards))
+        packed.append(util.pack_match_bmap(self.match))
+        packed.append(struct.pack("!L", self.instructions))
+        packed.append(struct.pack("!L", self.write_actions))
+        packed.append(struct.pack("!L", self.apply_actions))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.max_entries))
+        packed.append(struct.pack("!L", self.active_count))
+        packed.append(struct.pack("!Q", self.lookup_count))
+        packed.append(struct.pack("!Q", self.matched_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_entry()
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(7)
+        obj.name = reader.read("!32s")[0].rstrip("\x00")
+        obj.wildcards = util.unpack_wc_bmap(reader)
+        obj.match = util.unpack_match_bmap(reader)
+        obj.instructions = reader.read("!L")[0]
+        obj.write_actions = reader.read("!L")[0]
+        obj.apply_actions = reader.read("!L")[0]
+        obj.config = reader.read("!L")[0]
+        obj.max_entries = reader.read("!L")[0]
+        obj.active_count = reader.read("!L")[0]
+        obj.lookup_count = reader.read("!Q")[0]
+        obj.matched_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.name != other.name: return False
+        if self.wildcards != other.wildcards: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        if self.write_actions != other.write_actions: return False
+        if self.apply_actions != other.apply_actions: return False
+        if self.config != other.config: return False
+        if self.max_entries != other.max_entries: return False
+        if self.active_count != other.active_count: return False
+        if self.lookup_count != other.lookup_count: return False
+        if self.matched_count != other.matched_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("wildcards = ");
+                q.text(util.pretty_wildcards(self.wildcards))
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.text("%#x" % self.instructions)
+                q.text(","); q.breakable()
+                q.text("write_actions = ");
+                q.text("%#x" % self.write_actions)
+                q.text(","); q.breakable()
+                q.text("apply_actions = ");
+                q.text("%#x" % self.apply_actions)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("max_entries = ");
+                q.text("%#x" % self.max_entries)
+                q.text(","); q.breakable()
+                q.text("active_count = ");
+                q.text("%#x" % self.active_count)
+                q.text(","); q.breakable()
+                q.text("lookup_count = ");
+                q.text("%#x" % self.lookup_count)
+                q.text(","); q.breakable()
+                q.text("matched_count = ");
+                q.text("%#x" % self.matched_count)
+            q.breakable()
+        q.text('}')
+
+
+
+match = match_v2
diff --git a/Fabric/Utilities/src/python/loxi/of11/const.py b/Fabric/Utilities/src/python/loxi/of11/const.py
new file mode 100644
index 0000000..b131b78
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of11/const.py
@@ -0,0 +1,736 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template const.py
+# Do not modify
+
+OFP_VERSION = 2
+
+# Identifiers from group macro_definitions
+OFP_MAX_TABLE_NAME_LEN = 32
+OFP_MAX_PORT_NAME_LEN = 16
+OFP_TCP_PORT = 6653
+OFP_SSL_PORT = 6653
+OFP_ETH_ALEN = 6
+OFP_DEFAULT_MISS_SEND_LEN = 128
+OFPFW_ICMP_TYPE = 64
+OFPFW_ICMP_CODE = 128
+OFP_DL_TYPE_ETH2_CUTOFF = 1536
+OFP_DL_TYPE_NOT_ETH_TYPE = 1535
+OFP_VLAN_NONE = 0
+OFPMT_STANDARD_LENGTH = 88
+OFP_FLOW_PERMANENT = 0
+OFP_DEFAULT_PRIORITY = 32768
+DESC_STR_LEN = 256
+SERIAL_NUM_LEN = 32
+OFPQ_ALL = 4294967295
+OFPQ_MIN_RATE_UNCFG = 65535
+
+# Identifiers from group of_bsn_pdu_slot_num
+BSN_PDU_SLOT_NUM_ANY = 255
+
+of_bsn_pdu_slot_num_map = {
+    255: 'BSN_PDU_SLOT_NUM_ANY',
+}
+
+# Identifiers from group ofp_action_type
+OFPAT_OUTPUT = 0
+OFPAT_SET_VLAN_VID = 1
+OFPAT_SET_VLAN_PCP = 2
+OFPAT_SET_DL_SRC = 3
+OFPAT_SET_DL_DST = 4
+OFPAT_SET_NW_SRC = 5
+OFPAT_SET_NW_DST = 6
+OFPAT_SET_NW_TOS = 7
+OFPAT_SET_NW_ECN = 8
+OFPAT_SET_TP_SRC = 9
+OFPAT_SET_TP_DST = 10
+OFPAT_COPY_TTL_OUT = 11
+OFPAT_COPY_TTL_IN = 12
+OFPAT_SET_MPLS_LABEL = 13
+OFPAT_SET_MPLS_TC = 14
+OFPAT_SET_MPLS_TTL = 15
+OFPAT_DEC_MPLS_TTL = 16
+OFPAT_PUSH_VLAN = 17
+OFPAT_POP_VLAN = 18
+OFPAT_PUSH_MPLS = 19
+OFPAT_POP_MPLS = 20
+OFPAT_SET_QUEUE = 21
+OFPAT_GROUP = 22
+OFPAT_SET_NW_TTL = 23
+OFPAT_DEC_NW_TTL = 24
+OFPAT_EXPERIMENTER = 65535
+
+ofp_action_type_map = {
+    0: 'OFPAT_OUTPUT',
+    1: 'OFPAT_SET_VLAN_VID',
+    2: 'OFPAT_SET_VLAN_PCP',
+    3: 'OFPAT_SET_DL_SRC',
+    4: 'OFPAT_SET_DL_DST',
+    5: 'OFPAT_SET_NW_SRC',
+    6: 'OFPAT_SET_NW_DST',
+    7: 'OFPAT_SET_NW_TOS',
+    8: 'OFPAT_SET_NW_ECN',
+    9: 'OFPAT_SET_TP_SRC',
+    10: 'OFPAT_SET_TP_DST',
+    11: 'OFPAT_COPY_TTL_OUT',
+    12: 'OFPAT_COPY_TTL_IN',
+    13: 'OFPAT_SET_MPLS_LABEL',
+    14: 'OFPAT_SET_MPLS_TC',
+    15: 'OFPAT_SET_MPLS_TTL',
+    16: 'OFPAT_DEC_MPLS_TTL',
+    17: 'OFPAT_PUSH_VLAN',
+    18: 'OFPAT_POP_VLAN',
+    19: 'OFPAT_PUSH_MPLS',
+    20: 'OFPAT_POP_MPLS',
+    21: 'OFPAT_SET_QUEUE',
+    22: 'OFPAT_GROUP',
+    23: 'OFPAT_SET_NW_TTL',
+    24: 'OFPAT_DEC_NW_TTL',
+    65535: 'OFPAT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_bad_action_code
+OFPBAC_BAD_TYPE = 0
+OFPBAC_BAD_LEN = 1
+OFPBAC_BAD_EXPERIMENTER = 2
+OFPBAC_BAD_EXPERIMENTER_TYPE = 3
+OFPBAC_BAD_OUT_PORT = 4
+OFPBAC_BAD_ARGUMENT = 5
+OFPBAC_EPERM = 6
+OFPBAC_TOO_MANY = 7
+OFPBAC_BAD_QUEUE = 8
+OFPBAC_BAD_OUT_GROUP = 9
+OFPBAC_MATCH_INCONSISTENT = 10
+OFPBAC_UNSUPPORTED_ORDER = 11
+OFPBAC_BAD_TAG = 12
+
+ofp_bad_action_code_map = {
+    0: 'OFPBAC_BAD_TYPE',
+    1: 'OFPBAC_BAD_LEN',
+    2: 'OFPBAC_BAD_EXPERIMENTER',
+    3: 'OFPBAC_BAD_EXPERIMENTER_TYPE',
+    4: 'OFPBAC_BAD_OUT_PORT',
+    5: 'OFPBAC_BAD_ARGUMENT',
+    6: 'OFPBAC_EPERM',
+    7: 'OFPBAC_TOO_MANY',
+    8: 'OFPBAC_BAD_QUEUE',
+    9: 'OFPBAC_BAD_OUT_GROUP',
+    10: 'OFPBAC_MATCH_INCONSISTENT',
+    11: 'OFPBAC_UNSUPPORTED_ORDER',
+    12: 'OFPBAC_BAD_TAG',
+}
+
+# Identifiers from group ofp_bad_instruction_code
+OFPBIC_UNKNOWN_INST = 0
+OFPBIC_UNSUP_INST = 1
+OFPBIC_BAD_TABLE_ID = 2
+OFPBIC_UNSUP_METADATA = 3
+OFPBIC_UNSUP_METADATA_MASK = 4
+OFPBIC_UNSUP_EXP_INST = 5
+
+ofp_bad_instruction_code_map = {
+    0: 'OFPBIC_UNKNOWN_INST',
+    1: 'OFPBIC_UNSUP_INST',
+    2: 'OFPBIC_BAD_TABLE_ID',
+    3: 'OFPBIC_UNSUP_METADATA',
+    4: 'OFPBIC_UNSUP_METADATA_MASK',
+    5: 'OFPBIC_UNSUP_EXP_INST',
+}
+
+# Identifiers from group ofp_bad_match_code
+OFPBMC_BAD_TYPE = 0
+OFPBMC_BAD_LEN = 1
+OFPBMC_BAD_TAG = 2
+OFPBMC_BAD_DL_ADDR_MASK = 3
+OFPBMC_BAD_NW_ADDR_MASK = 4
+OFPBMC_BAD_WILDCARDS = 5
+OFPBMC_BAD_FIELD = 6
+OFPBMC_BAD_VALUE = 7
+
+ofp_bad_match_code_map = {
+    0: 'OFPBMC_BAD_TYPE',
+    1: 'OFPBMC_BAD_LEN',
+    2: 'OFPBMC_BAD_TAG',
+    3: 'OFPBMC_BAD_DL_ADDR_MASK',
+    4: 'OFPBMC_BAD_NW_ADDR_MASK',
+    5: 'OFPBMC_BAD_WILDCARDS',
+    6: 'OFPBMC_BAD_FIELD',
+    7: 'OFPBMC_BAD_VALUE',
+}
+
+# Identifiers from group ofp_bad_request_code
+OFPBRC_BAD_VERSION = 0
+OFPBRC_BAD_TYPE = 1
+OFPBRC_BAD_STAT = 2
+OFPBRC_BAD_EXPERIMENTER = 3
+OFPBRC_BAD_SUBTYPE = 4
+OFPBRC_EPERM = 5
+OFPBRC_BAD_LEN = 6
+OFPBRC_BUFFER_EMPTY = 7
+OFPBRC_BUFFER_UNKNOWN = 8
+OFPBRC_BAD_TABLE_ID = 9
+
+ofp_bad_request_code_map = {
+    0: 'OFPBRC_BAD_VERSION',
+    1: 'OFPBRC_BAD_TYPE',
+    2: 'OFPBRC_BAD_STAT',
+    3: 'OFPBRC_BAD_EXPERIMENTER',
+    4: 'OFPBRC_BAD_SUBTYPE',
+    5: 'OFPBRC_EPERM',
+    6: 'OFPBRC_BAD_LEN',
+    7: 'OFPBRC_BUFFER_EMPTY',
+    8: 'OFPBRC_BUFFER_UNKNOWN',
+    9: 'OFPBRC_BAD_TABLE_ID',
+}
+
+# Identifiers from group ofp_bsn_vport_l2gre_flags
+OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID = 1
+OF_BSN_VPORT_L2GRE_DSCP_ASSIGN = 2
+OF_BSN_VPORT_L2GRE_DSCP_COPY = 4
+OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID = 8
+OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID = 16
+
+ofp_bsn_vport_l2gre_flags_map = {
+    1: 'OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID',
+    2: 'OF_BSN_VPORT_L2GRE_DSCP_ASSIGN',
+    4: 'OF_BSN_VPORT_L2GRE_DSCP_COPY',
+    8: 'OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID',
+    16: 'OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID',
+}
+
+# Identifiers from group ofp_bsn_vport_q_in_q_untagged
+OF_BSN_VPORT_Q_IN_Q_UNTAGGED = 65535
+
+ofp_bsn_vport_q_in_q_untagged_map = {
+    65535: 'OF_BSN_VPORT_Q_IN_Q_UNTAGGED',
+}
+
+# Identifiers from group ofp_bsn_vport_status
+OF_BSN_VPORT_STATUS_OK = 0
+OF_BSN_VPORT_STATUS_FAILED = 1
+
+ofp_bsn_vport_status_map = {
+    0: 'OF_BSN_VPORT_STATUS_OK',
+    1: 'OF_BSN_VPORT_STATUS_FAILED',
+}
+
+# Identifiers from group ofp_capabilities
+OFPC_FLOW_STATS = 1
+OFPC_TABLE_STATS = 2
+OFPC_PORT_STATS = 4
+OFPC_GROUP_STATS = 8
+OFPC_IP_REASM = 32
+OFPC_QUEUE_STATS = 64
+OFPC_ARP_MATCH_IP = 128
+
+ofp_capabilities_map = {
+    1: 'OFPC_FLOW_STATS',
+    2: 'OFPC_TABLE_STATS',
+    4: 'OFPC_PORT_STATS',
+    8: 'OFPC_GROUP_STATS',
+    32: 'OFPC_IP_REASM',
+    64: 'OFPC_QUEUE_STATS',
+    128: 'OFPC_ARP_MATCH_IP',
+}
+
+# Identifiers from group ofp_config_flags
+OFPC_FRAG_NORMAL = 0
+OFPC_FRAG_DROP = 1
+OFPC_FRAG_REASM = 2
+OFPC_FRAG_MASK = 3
+OFPC_INVALID_TTL_TO_CONTROLLER = 4
+
+ofp_config_flags_map = {
+    0: 'OFPC_FRAG_NORMAL',
+    1: 'OFPC_FRAG_DROP',
+    2: 'OFPC_FRAG_REASM',
+    3: 'OFPC_FRAG_MASK',
+    4: 'OFPC_INVALID_TTL_TO_CONTROLLER',
+}
+
+# Identifiers from group ofp_error_type
+OFPET_HELLO_FAILED = 0
+OFPET_BAD_REQUEST = 1
+OFPET_BAD_ACTION = 2
+OFPET_BAD_INSTRUCTION = 3
+OFPET_BAD_MATCH = 4
+OFPET_FLOW_MOD_FAILED = 5
+OFPET_GROUP_MOD_FAILED = 6
+OFPET_PORT_MOD_FAILED = 7
+OFPET_TABLE_MOD_FAILED = 8
+OFPET_QUEUE_OP_FAILED = 9
+OFPET_SWITCH_CONFIG_FAILED = 10
+
+ofp_error_type_map = {
+    0: 'OFPET_HELLO_FAILED',
+    1: 'OFPET_BAD_REQUEST',
+    2: 'OFPET_BAD_ACTION',
+    3: 'OFPET_BAD_INSTRUCTION',
+    4: 'OFPET_BAD_MATCH',
+    5: 'OFPET_FLOW_MOD_FAILED',
+    6: 'OFPET_GROUP_MOD_FAILED',
+    7: 'OFPET_PORT_MOD_FAILED',
+    8: 'OFPET_TABLE_MOD_FAILED',
+    9: 'OFPET_QUEUE_OP_FAILED',
+    10: 'OFPET_SWITCH_CONFIG_FAILED',
+}
+
+# Identifiers from group ofp_flow_mod_command
+OFPFC_ADD = 0
+OFPFC_MODIFY = 1
+OFPFC_MODIFY_STRICT = 2
+OFPFC_DELETE = 3
+OFPFC_DELETE_STRICT = 4
+
+ofp_flow_mod_command_map = {
+    0: 'OFPFC_ADD',
+    1: 'OFPFC_MODIFY',
+    2: 'OFPFC_MODIFY_STRICT',
+    3: 'OFPFC_DELETE',
+    4: 'OFPFC_DELETE_STRICT',
+}
+
+# Identifiers from group ofp_flow_mod_failed_code
+OFPFMFC_UNKNOWN = 0
+OFPFMFC_TABLE_FULL = 1
+OFPFMFC_BAD_TABLE_ID = 2
+OFPFMFC_OVERLAP = 3
+OFPFMFC_EPERM = 4
+OFPFMFC_BAD_TIMEOUT = 5
+OFPFMFC_BAD_COMMAND = 6
+
+ofp_flow_mod_failed_code_map = {
+    0: 'OFPFMFC_UNKNOWN',
+    1: 'OFPFMFC_TABLE_FULL',
+    2: 'OFPFMFC_BAD_TABLE_ID',
+    3: 'OFPFMFC_OVERLAP',
+    4: 'OFPFMFC_EPERM',
+    5: 'OFPFMFC_BAD_TIMEOUT',
+    6: 'OFPFMFC_BAD_COMMAND',
+}
+
+# Identifiers from group ofp_flow_mod_flags
+OFPFF_SEND_FLOW_REM = 1
+OFPFF_CHECK_OVERLAP = 2
+
+ofp_flow_mod_flags_map = {
+    1: 'OFPFF_SEND_FLOW_REM',
+    2: 'OFPFF_CHECK_OVERLAP',
+}
+
+# Identifiers from group ofp_flow_removed_reason
+OFPRR_IDLE_TIMEOUT = 0
+OFPRR_HARD_TIMEOUT = 1
+OFPRR_DELETE = 2
+OFPRR_GROUP_DELETE = 3
+
+ofp_flow_removed_reason_map = {
+    0: 'OFPRR_IDLE_TIMEOUT',
+    1: 'OFPRR_HARD_TIMEOUT',
+    2: 'OFPRR_DELETE',
+    3: 'OFPRR_GROUP_DELETE',
+}
+
+# Identifiers from group ofp_flow_wildcards
+OFPFW_IN_PORT = 1
+OFPFW_DL_VLAN = 2
+OFPFW_DL_VLAN_PCP = 4
+OFPFW_DL_TYPE = 8
+OFPFW_NW_TOS = 16
+OFPFW_NW_PROTO = 32
+OFPFW_TP_SRC = 64
+OFPFW_TP_DST = 128
+OFPFW_MPLS_LABEL = 256
+OFPFW_MPLS_TC = 512
+OFPFW_ALL = 1023
+
+ofp_flow_wildcards_map = {
+    1: 'OFPFW_IN_PORT',
+    2: 'OFPFW_DL_VLAN',
+    4: 'OFPFW_DL_VLAN_PCP',
+    8: 'OFPFW_DL_TYPE',
+    16: 'OFPFW_NW_TOS',
+    32: 'OFPFW_NW_PROTO',
+    64: 'OFPFW_TP_SRC',
+    128: 'OFPFW_TP_DST',
+    256: 'OFPFW_MPLS_LABEL',
+    512: 'OFPFW_MPLS_TC',
+}
+
+# Identifiers from group ofp_group
+OFPG_MAX = 4294967040
+OFPG_ALL = 4294967292
+OFPG_ANY = 4294967295
+
+ofp_group_map = {
+    4294967040: 'OFPG_MAX',
+    4294967292: 'OFPG_ALL',
+    4294967295: 'OFPG_ANY',
+}
+
+# Identifiers from group ofp_group_mod_command
+OFPGC_ADD = 0
+OFPGC_MODIFY = 1
+OFPGC_DELETE = 2
+
+ofp_group_mod_command_map = {
+    0: 'OFPGC_ADD',
+    1: 'OFPGC_MODIFY',
+    2: 'OFPGC_DELETE',
+}
+
+# Identifiers from group ofp_group_mod_failed_code
+OFPGMFC_GROUP_EXISTS = 0
+OFPGMFC_INVALID_GROUP = 1
+OFPGMFC_WEIGHT_UNSUPPORTED = 2
+OFPGMFC_OUT_OF_GROUPS = 3
+OFPGMFC_OUT_OF_BUCKETS = 4
+OFPGMFC_CHAINING_UNSUPPORTED = 5
+OFPGMFC_WATCH_UNSUPPORTED = 6
+OFPGMFC_LOOP = 7
+OFPGMFC_UNKNOWN_GROUP = 8
+
+ofp_group_mod_failed_code_map = {
+    0: 'OFPGMFC_GROUP_EXISTS',
+    1: 'OFPGMFC_INVALID_GROUP',
+    2: 'OFPGMFC_WEIGHT_UNSUPPORTED',
+    3: 'OFPGMFC_OUT_OF_GROUPS',
+    4: 'OFPGMFC_OUT_OF_BUCKETS',
+    5: 'OFPGMFC_CHAINING_UNSUPPORTED',
+    6: 'OFPGMFC_WATCH_UNSUPPORTED',
+    7: 'OFPGMFC_LOOP',
+    8: 'OFPGMFC_UNKNOWN_GROUP',
+}
+
+# Identifiers from group ofp_group_type
+OFPGT_ALL = 0
+OFPGT_SELECT = 1
+OFPGT_INDIRECT = 2
+OFPGT_FF = 3
+
+ofp_group_type_map = {
+    0: 'OFPGT_ALL',
+    1: 'OFPGT_SELECT',
+    2: 'OFPGT_INDIRECT',
+    3: 'OFPGT_FF',
+}
+
+# Identifiers from group ofp_hello_failed_code
+OFPHFC_INCOMPATIBLE = 0
+OFPHFC_EPERM = 1
+
+ofp_hello_failed_code_map = {
+    0: 'OFPHFC_INCOMPATIBLE',
+    1: 'OFPHFC_EPERM',
+}
+
+# Identifiers from group ofp_instruction_type
+OFPIT_GOTO_TABLE = 1
+OFPIT_WRITE_METADATA = 2
+OFPIT_WRITE_ACTIONS = 3
+OFPIT_APPLY_ACTIONS = 4
+OFPIT_CLEAR_ACTIONS = 5
+OFPIT_EXPERIMENTER = 65535
+
+ofp_instruction_type_map = {
+    1: 'OFPIT_GOTO_TABLE',
+    2: 'OFPIT_WRITE_METADATA',
+    3: 'OFPIT_WRITE_ACTIONS',
+    4: 'OFPIT_APPLY_ACTIONS',
+    5: 'OFPIT_CLEAR_ACTIONS',
+    65535: 'OFPIT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_match_type
+OFPMT_STANDARD = 0
+
+ofp_match_type_map = {
+    0: 'OFPMT_STANDARD',
+}
+
+# Identifiers from group ofp_packet_in_reason
+OFPR_NO_MATCH = 0
+OFPR_ACTION = 1
+
+ofp_packet_in_reason_map = {
+    0: 'OFPR_NO_MATCH',
+    1: 'OFPR_ACTION',
+}
+
+# Identifiers from group ofp_port
+OFPP_MAX = 4294967040
+OFPP_IN_PORT = 4294967288
+OFPP_TABLE = 4294967289
+OFPP_NORMAL = 4294967290
+OFPP_FLOOD = 4294967291
+OFPP_ALL = 4294967292
+OFPP_CONTROLLER = 4294967293
+OFPP_LOCAL = 4294967294
+OFPP_ANY = 4294967295
+
+ofp_port_map = {
+    4294967040: 'OFPP_MAX',
+    4294967288: 'OFPP_IN_PORT',
+    4294967289: 'OFPP_TABLE',
+    4294967290: 'OFPP_NORMAL',
+    4294967291: 'OFPP_FLOOD',
+    4294967292: 'OFPP_ALL',
+    4294967293: 'OFPP_CONTROLLER',
+    4294967294: 'OFPP_LOCAL',
+    4294967295: 'OFPP_ANY',
+}
+
+# Identifiers from group ofp_port_config
+OFPPC_PORT_DOWN = 1
+OFPPC_NO_RECV = 4
+OFPPC_NO_FWD = 32
+OFPPC_NO_PACKET_IN = 64
+OFPPC_BSN_MIRROR_DEST = 2147483648
+
+ofp_port_config_map = {
+    1: 'OFPPC_PORT_DOWN',
+    4: 'OFPPC_NO_RECV',
+    32: 'OFPPC_NO_FWD',
+    64: 'OFPPC_NO_PACKET_IN',
+    2147483648: 'OFPPC_BSN_MIRROR_DEST',
+}
+
+# Identifiers from group ofp_port_features
+OFPPF_10MB_HD = 1
+OFPPF_10MB_FD = 2
+OFPPF_100MB_HD = 4
+OFPPF_100MB_FD = 8
+OFPPF_1GB_HD = 16
+OFPPF_1GB_FD = 32
+OFPPF_10GB_FD = 64
+OFPPF_40GB_FD = 128
+OFPPF_100GB_FD = 256
+OFPPF_1TB_FD = 512
+OFPPF_OTHER = 1024
+OFPPF_COPPER = 2048
+OFPPF_FIBER = 4096
+OFPPF_AUTONEG = 8192
+OFPPF_PAUSE = 16384
+OFPPF_PAUSE_ASYM = 32768
+
+ofp_port_features_map = {
+    1: 'OFPPF_10MB_HD',
+    2: 'OFPPF_10MB_FD',
+    4: 'OFPPF_100MB_HD',
+    8: 'OFPPF_100MB_FD',
+    16: 'OFPPF_1GB_HD',
+    32: 'OFPPF_1GB_FD',
+    64: 'OFPPF_10GB_FD',
+    128: 'OFPPF_40GB_FD',
+    256: 'OFPPF_100GB_FD',
+    512: 'OFPPF_1TB_FD',
+    1024: 'OFPPF_OTHER',
+    2048: 'OFPPF_COPPER',
+    4096: 'OFPPF_FIBER',
+    8192: 'OFPPF_AUTONEG',
+    16384: 'OFPPF_PAUSE',
+    32768: 'OFPPF_PAUSE_ASYM',
+}
+
+# Identifiers from group ofp_port_mod_failed_code
+OFPPMFC_BAD_PORT = 0
+OFPPMFC_BAD_HW_ADDR = 1
+OFPPMFC_BAD_CONFIG = 2
+OFPPMFC_BAD_ADVERTISE = 3
+
+ofp_port_mod_failed_code_map = {
+    0: 'OFPPMFC_BAD_PORT',
+    1: 'OFPPMFC_BAD_HW_ADDR',
+    2: 'OFPPMFC_BAD_CONFIG',
+    3: 'OFPPMFC_BAD_ADVERTISE',
+}
+
+# Identifiers from group ofp_port_reason
+OFPPR_ADD = 0
+OFPPR_DELETE = 1
+OFPPR_MODIFY = 2
+
+ofp_port_reason_map = {
+    0: 'OFPPR_ADD',
+    1: 'OFPPR_DELETE',
+    2: 'OFPPR_MODIFY',
+}
+
+# Identifiers from group ofp_port_state
+OFPPS_LINK_DOWN = 1
+OFPPS_BLOCKED = 2
+OFPPS_LIVE = 4
+
+ofp_port_state_map = {
+    1: 'OFPPS_LINK_DOWN',
+    2: 'OFPPS_BLOCKED',
+    4: 'OFPPS_LIVE',
+}
+
+# Identifiers from group ofp_queue_op_failed_code
+OFPQOFC_BAD_PORT = 0
+OFPQOFC_BAD_QUEUE = 1
+OFPQOFC_EPERM = 2
+
+ofp_queue_op_failed_code_map = {
+    0: 'OFPQOFC_BAD_PORT',
+    1: 'OFPQOFC_BAD_QUEUE',
+    2: 'OFPQOFC_EPERM',
+}
+
+# Identifiers from group ofp_queue_properties
+OFPQT_NONE = 0
+OFPQT_MIN_RATE = 1
+
+ofp_queue_properties_map = {
+    0: 'OFPQT_NONE',
+    1: 'OFPQT_MIN_RATE',
+}
+
+# Identifiers from group ofp_stats_reply_flags
+OFPSF_REPLY_MORE = 1
+
+ofp_stats_reply_flags_map = {
+    1: 'OFPSF_REPLY_MORE',
+}
+
+# Identifiers from group ofp_stats_request_flags
+
+ofp_stats_request_flags_map = {
+}
+
+# Identifiers from group ofp_stats_type
+OFPST_DESC = 0
+OFPST_FLOW = 1
+OFPST_AGGREGATE = 2
+OFPST_TABLE = 3
+OFPST_PORT = 4
+OFPST_QUEUE = 5
+OFPST_GROUP = 6
+OFPST_GROUP_DESC = 7
+OFPST_EXPERIMENTER = 65535
+
+ofp_stats_type_map = {
+    0: 'OFPST_DESC',
+    1: 'OFPST_FLOW',
+    2: 'OFPST_AGGREGATE',
+    3: 'OFPST_TABLE',
+    4: 'OFPST_PORT',
+    5: 'OFPST_QUEUE',
+    6: 'OFPST_GROUP',
+    7: 'OFPST_GROUP_DESC',
+    65535: 'OFPST_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_switch_config_failed_code
+OFPSCFC_BAD_FLAGS = 0
+OFPSCFC_BAD_LEN = 1
+
+ofp_switch_config_failed_code_map = {
+    0: 'OFPSCFC_BAD_FLAGS',
+    1: 'OFPSCFC_BAD_LEN',
+}
+
+# Identifiers from group ofp_table_config
+OFPTC_TABLE_MISS_CONTROLLER = 0
+OFPTC_TABLE_MISS_CONTINUE = 1
+OFPTC_TABLE_MISS_DROP = 2
+OFPTC_TABLE_MISS_MASK = 3
+
+ofp_table_config_map = {
+    0: 'OFPTC_TABLE_MISS_CONTROLLER',
+    1: 'OFPTC_TABLE_MISS_CONTINUE',
+    2: 'OFPTC_TABLE_MISS_DROP',
+    3: 'OFPTC_TABLE_MISS_MASK',
+}
+
+# Identifiers from group ofp_table_mod_failed_code
+OFPTMFC_BAD_TABLE = 0
+OFPTMFC_BAD_CONFIG = 1
+
+ofp_table_mod_failed_code_map = {
+    0: 'OFPTMFC_BAD_TABLE',
+    1: 'OFPTMFC_BAD_CONFIG',
+}
+
+# Identifiers from group ofp_type
+OFPT_HELLO = 0
+OFPT_ERROR = 1
+OFPT_ECHO_REQUEST = 2
+OFPT_ECHO_REPLY = 3
+OFPT_EXPERIMENTER = 4
+OFPT_FEATURES_REQUEST = 5
+OFPT_FEATURES_REPLY = 6
+OFPT_GET_CONFIG_REQUEST = 7
+OFPT_GET_CONFIG_REPLY = 8
+OFPT_SET_CONFIG = 9
+OFPT_PACKET_IN = 10
+OFPT_FLOW_REMOVED = 11
+OFPT_PORT_STATUS = 12
+OFPT_PACKET_OUT = 13
+OFPT_FLOW_MOD = 14
+OFPT_GROUP_MOD = 15
+OFPT_PORT_MOD = 16
+OFPT_TABLE_MOD = 17
+OFPT_STATS_REQUEST = 18
+OFPT_STATS_REPLY = 19
+OFPT_BARRIER_REQUEST = 20
+OFPT_BARRIER_REPLY = 21
+OFPT_QUEUE_GET_CONFIG_REQUEST = 22
+OFPT_QUEUE_GET_CONFIG_REPLY = 23
+
+ofp_type_map = {
+    0: 'OFPT_HELLO',
+    1: 'OFPT_ERROR',
+    2: 'OFPT_ECHO_REQUEST',
+    3: 'OFPT_ECHO_REPLY',
+    4: 'OFPT_EXPERIMENTER',
+    5: 'OFPT_FEATURES_REQUEST',
+    6: 'OFPT_FEATURES_REPLY',
+    7: 'OFPT_GET_CONFIG_REQUEST',
+    8: 'OFPT_GET_CONFIG_REPLY',
+    9: 'OFPT_SET_CONFIG',
+    10: 'OFPT_PACKET_IN',
+    11: 'OFPT_FLOW_REMOVED',
+    12: 'OFPT_PORT_STATUS',
+    13: 'OFPT_PACKET_OUT',
+    14: 'OFPT_FLOW_MOD',
+    15: 'OFPT_GROUP_MOD',
+    16: 'OFPT_PORT_MOD',
+    17: 'OFPT_TABLE_MOD',
+    18: 'OFPT_STATS_REQUEST',
+    19: 'OFPT_STATS_REPLY',
+    20: 'OFPT_BARRIER_REQUEST',
+    21: 'OFPT_BARRIER_REPLY',
+    22: 'OFPT_QUEUE_GET_CONFIG_REQUEST',
+    23: 'OFPT_QUEUE_GET_CONFIG_REPLY',
+}
+
+# Identifiers from group ofp_vlan_id
+OFPVID_ANY = 65534
+OFPVID_NONE = 65535
+
+ofp_vlan_id_map = {
+    65534: 'OFPVID_ANY',
+    65535: 'OFPVID_NONE',
+}
+
diff --git a/Fabric/Utilities/src/python/loxi/of11/instruction.py b/Fabric/Utilities/src/python/loxi/of11/instruction.py
new file mode 100644
index 0000000..eb0f517
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of11/instruction.py
@@ -0,0 +1,389 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of11']
+
+class instruction(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = instruction.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = instruction()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("instruction {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class apply_actions(instruction):
+    type = 4
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[4] = apply_actions
+
+class clear_actions(instruction):
+    type = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = clear_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("clear_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[5] = clear_actions
+
+class experimenter(instruction):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[65535] = experimenter
+
+class goto_table(instruction):
+    type = 1
+
+    def __init__(self, table_id=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = goto_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("goto_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[1] = goto_table
+
+class write_actions(instruction):
+    type = 3
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[3] = write_actions
+
+class write_metadata(instruction):
+    type = 2
+
+    def __init__(self, metadata=None, metadata_mask=None):
+        if metadata != None:
+            self.metadata = metadata
+        else:
+            self.metadata = 0
+        if metadata_mask != None:
+            self.metadata_mask = metadata_mask
+        else:
+            self.metadata_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.metadata))
+        packed.append(struct.pack("!Q", self.metadata_mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_metadata()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.metadata = reader.read("!Q")[0]
+        obj.metadata_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.metadata != other.metadata: return False
+        if self.metadata_mask != other.metadata_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("metadata = ");
+                q.text("%#x" % self.metadata)
+                q.text(","); q.breakable()
+                q.text("metadata_mask = ");
+                q.text("%#x" % self.metadata_mask)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[2] = write_metadata
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of11/message.py b/Fabric/Utilities/src/python/loxi/of11/message.py
new file mode 100644
index 0000000..77ab080
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of11/message.py
@@ -0,0 +1,7859 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of11']
+
+class message(loxi.OFObject):
+    subtypes = {}
+
+    version = 2
+
+    def __init__(self, type=None, xid=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 1)
+        subclass = message.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = message()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        obj.type = reader.read("!B")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("message {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+
+class stats_reply(message):
+    subtypes = {}
+
+    version = 2
+    type = 19
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[19] = stats_reply
+
+class aggregate_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, packet_count=None, byte_count=None, flow_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if flow_count != None:
+            self.flow_count = flow_count
+        else:
+            self.flow_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(struct.pack("!L", self.flow_count))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.flow_count = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.flow_count != other.flow_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("flow_count = ");
+                q.text("%#x" % self.flow_count)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[2] = aggregate_stats_reply
+
+class stats_request(message):
+    subtypes = {}
+
+    version = 2
+    type = 18
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[18] = stats_request
+
+class aggregate_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[2] = aggregate_stats_request
+
+class error_msg(message):
+    subtypes = {}
+
+    version = 2
+    type = 1
+
+    def __init__(self, xid=None, err_type=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if err_type != None:
+            self.err_type = err_type
+        else:
+            self.err_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = error_msg.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.err_type = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.err_type != other.err_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[1] = error_msg
+
+class bad_action_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 2
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_action_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 2)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_action_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[2] = bad_action_error_msg
+
+class bad_instruction_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 3
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_instruction_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 3)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_instruction_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[3] = bad_instruction_error_msg
+
+class bad_match_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 4
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_match_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 4)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_match_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[4] = bad_match_error_msg
+
+class bad_request_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 1
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_request_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 1)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_request_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[1] = bad_request_error_msg
+
+class barrier_reply(message):
+    version = 2
+    type = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 21)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[21] = barrier_reply
+
+class barrier_request(message):
+    version = 2
+    type = 20
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 20)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[20] = barrier_request
+
+class experimenter(message):
+    subtypes = {}
+
+    version = 2
+    type = 4
+
+    def __init__(self, xid=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[4] = experimenter
+
+class bsn_header(experimenter):
+    subtypes = {}
+
+    version = 2
+    type = 4
+    experimenter = 6035143
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = bsn_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn_header
+
+class bsn_bw_clear_data_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 22
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 22)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[22] = bsn_bw_clear_data_reply
+
+class bsn_bw_clear_data_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 21)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[21] = bsn_bw_clear_data_request
+
+class bsn_bw_enable_get_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 20
+
+    def __init__(self, xid=None, enabled=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enabled))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 20)
+        obj.enabled = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[20] = bsn_bw_enable_get_reply
+
+class bsn_bw_enable_get_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 19
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 19)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[19] = bsn_bw_enable_get_request
+
+class bsn_bw_enable_set_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 23
+
+    def __init__(self, xid=None, enable=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 23)
+        obj.enable = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[23] = bsn_bw_enable_set_reply
+
+class bsn_bw_enable_set_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 18
+
+    def __init__(self, xid=None, enable=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 18)
+        obj.enable = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[18] = bsn_bw_enable_set_request
+
+class bsn_get_interfaces_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, interfaces=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if interfaces != None:
+            self.interfaces = interfaces
+        else:
+            self.interfaces = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.interfaces))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.interfaces = loxi.generic_util.unpack_list(reader, ofp.common.bsn_interface.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.interfaces != other.interfaces: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("interfaces = ");
+                q.pp(self.interfaces)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[10] = bsn_get_interfaces_reply
+
+class bsn_get_interfaces_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[9] = bsn_get_interfaces_request
+
+class bsn_get_mirroring_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[5] = bsn_get_mirroring_reply
+
+class bsn_get_mirroring_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[4] = bsn_get_mirroring_request
+
+class bsn_pdu_rx_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 34
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 34)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[34] = bsn_pdu_rx_reply
+
+class bsn_pdu_rx_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 33
+
+    def __init__(self, xid=None, timeout_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if timeout_ms != None:
+            self.timeout_ms = timeout_ms
+        else:
+            self.timeout_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.timeout_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 33)
+        obj.timeout_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.timeout_ms != other.timeout_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("timeout_ms = ");
+                q.text("%#x" % self.timeout_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[33] = bsn_pdu_rx_request
+
+class bsn_pdu_rx_timeout(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 35
+
+    def __init__(self, xid=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_timeout()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 35)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[35] = bsn_pdu_rx_timeout
+
+class bsn_pdu_tx_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 32
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 32)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[32] = bsn_pdu_tx_reply
+
+class bsn_pdu_tx_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 31
+
+    def __init__(self, xid=None, tx_interval_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if tx_interval_ms != None:
+            self.tx_interval_ms = tx_interval_ms
+        else:
+            self.tx_interval_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.tx_interval_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 31)
+        obj.tx_interval_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.tx_interval_ms != other.tx_interval_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("tx_interval_ms = ");
+                q.text("%#x" % self.tx_interval_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[31] = bsn_pdu_tx_request
+
+class bsn_set_mirroring(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_mirroring()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_mirroring {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[3] = bsn_set_mirroring
+
+class bsn_set_pktin_suppression_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 25
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 25)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[25] = bsn_set_pktin_suppression_reply
+
+class bsn_set_pktin_suppression_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, enabled=None, idle_timeout=None, hard_timeout=None, priority=None, cookie=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.enabled))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!Q", self.cookie))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.enabled = reader.read("!B")[0]
+        reader.skip(1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.cookie = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.cookie != other.cookie: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[11] = bsn_set_pktin_suppression_request
+
+class experimenter_stats_reply(stats_reply):
+    subtypes = {}
+
+    version = 2
+    type = 19
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append('\x00' * 4)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        reader.skip(4)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[65535] = experimenter_stats_reply
+
+class bsn_stats_reply(experimenter_stats_reply):
+    subtypes = {}
+
+    version = 2
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_reply.subtypes[6035143] = bsn_stats_reply
+
+class experimenter_stats_request(stats_request):
+    subtypes = {}
+
+    version = 2
+    type = 18
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append('\x00' * 4)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        reader.skip(4)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[65535] = experimenter_stats_request
+
+class bsn_stats_request(experimenter_stats_request):
+    subtypes = {}
+
+    version = 2
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_request.subtypes[6035143] = bsn_stats_request
+
+class bsn_virtual_port_create_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, status=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.status = reader.read("!L")[0]
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[16] = bsn_virtual_port_create_reply
+
+class bsn_virtual_port_create_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, vport=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport != None:
+            self.vport = vport
+        else:
+            self.vport = ofp.bsn_vport()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.vport.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.vport = ofp.bsn_vport.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport != other.vport: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport = ");
+                q.pp(self.vport)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[15] = bsn_virtual_port_create_request
+
+class bsn_virtual_port_remove_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 26
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 26)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[26] = bsn_virtual_port_remove_reply
+
+class bsn_virtual_port_remove_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 17
+
+    def __init__(self, xid=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 17)
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[17] = bsn_virtual_port_remove_request
+
+class desc_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None, mfr_desc=None, hw_desc=None, sw_desc=None, serial_num=None, dp_desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if mfr_desc != None:
+            self.mfr_desc = mfr_desc
+        else:
+            self.mfr_desc = ""
+        if hw_desc != None:
+            self.hw_desc = hw_desc
+        else:
+            self.hw_desc = ""
+        if sw_desc != None:
+            self.sw_desc = sw_desc
+        else:
+            self.sw_desc = ""
+        if serial_num != None:
+            self.serial_num = serial_num
+        else:
+            self.serial_num = ""
+        if dp_desc != None:
+            self.dp_desc = dp_desc
+        else:
+            self.dp_desc = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!256s", self.mfr_desc))
+        packed.append(struct.pack("!256s", self.hw_desc))
+        packed.append(struct.pack("!256s", self.sw_desc))
+        packed.append(struct.pack("!32s", self.serial_num))
+        packed.append(struct.pack("!256s", self.dp_desc))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.mfr_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.hw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.sw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.serial_num = reader.read("!32s")[0].rstrip("\x00")
+        obj.dp_desc = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.mfr_desc != other.mfr_desc: return False
+        if self.hw_desc != other.hw_desc: return False
+        if self.sw_desc != other.sw_desc: return False
+        if self.serial_num != other.serial_num: return False
+        if self.dp_desc != other.dp_desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("mfr_desc = ");
+                q.pp(self.mfr_desc)
+                q.text(","); q.breakable()
+                q.text("hw_desc = ");
+                q.pp(self.hw_desc)
+                q.text(","); q.breakable()
+                q.text("sw_desc = ");
+                q.pp(self.sw_desc)
+                q.text(","); q.breakable()
+                q.text("serial_num = ");
+                q.pp(self.serial_num)
+                q.text(","); q.breakable()
+                q.text("dp_desc = ");
+                q.pp(self.dp_desc)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[0] = desc_stats_reply
+
+class desc_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[0] = desc_stats_request
+
+class echo_reply(message):
+    version = 2
+    type = 3
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[3] = echo_reply
+
+class echo_request(message):
+    version = 2
+    type = 2
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[2] = echo_request
+
+class features_reply(message):
+    version = 2
+    type = 6
+
+    def __init__(self, xid=None, datapath_id=None, n_buffers=None, n_tables=None, capabilities=None, reserved=None, ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if datapath_id != None:
+            self.datapath_id = datapath_id
+        else:
+            self.datapath_id = 0
+        if n_buffers != None:
+            self.n_buffers = n_buffers
+        else:
+            self.n_buffers = 0
+        if n_tables != None:
+            self.n_tables = n_tables
+        else:
+            self.n_tables = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if reserved != None:
+            self.reserved = reserved
+        else:
+            self.reserved = 0
+        if ports != None:
+            self.ports = ports
+        else:
+            self.ports = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.datapath_id))
+        packed.append(struct.pack("!L", self.n_buffers))
+        packed.append(struct.pack("!B", self.n_tables))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.reserved))
+        packed.append(loxi.generic_util.pack_list(self.ports))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.datapath_id = reader.read("!Q")[0]
+        obj.n_buffers = reader.read("!L")[0]
+        obj.n_tables = reader.read("!B")[0]
+        reader.skip(3)
+        obj.capabilities = reader.read("!L")[0]
+        obj.reserved = reader.read("!L")[0]
+        obj.ports = loxi.generic_util.unpack_list(reader, ofp.common.port_desc.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.datapath_id != other.datapath_id: return False
+        if self.n_buffers != other.n_buffers: return False
+        if self.n_tables != other.n_tables: return False
+        if self.capabilities != other.capabilities: return False
+        if self.reserved != other.reserved: return False
+        if self.ports != other.ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("datapath_id = ");
+                q.text("%#x" % self.datapath_id)
+                q.text(","); q.breakable()
+                q.text("n_buffers = ");
+                q.text("%#x" % self.n_buffers)
+                q.text(","); q.breakable()
+                q.text("n_tables = ");
+                q.text("%#x" % self.n_tables)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("reserved = ");
+                q.text("%#x" % self.reserved)
+                q.text(","); q.breakable()
+                q.text("ports = ");
+                q.pp(self.ports)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[6] = features_reply
+
+class features_request(message):
+    version = 2
+    type = 5
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[5] = features_request
+
+class flow_mod(message):
+    subtypes = {}
+
+    version = 2
+    type = 14
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, _command=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if _command != None:
+            self._command = _command
+        else:
+            self._command = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 25)
+        subclass = flow_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = flow_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj._command = util.unpack_fm_cmd(reader)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self._command != other._command: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[14] = flow_mod
+
+class flow_add(flow_mod):
+    version = 2
+    type = 14
+    _command = 0
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 0)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[0] = flow_add
+
+class flow_delete(flow_mod):
+    version = 2
+    type = 14
+    _command = 3
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 3)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[3] = flow_delete
+
+class flow_delete_strict(flow_mod):
+    version = 2
+    type = 14
+    _command = 4
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 4)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[4] = flow_delete_strict
+
+class flow_mod_failed_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 5
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 5)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[5] = flow_mod_failed_error_msg
+
+class flow_modify(flow_mod):
+    version = 2
+    type = 14
+    _command = 1
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[1] = flow_modify
+
+class flow_modify_strict(flow_mod):
+    version = 2
+    type = 14
+    _command = 2
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 2)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[2] = flow_modify_strict
+
+class flow_removed(message):
+    version = 2
+    type = 11
+
+    def __init__(self, xid=None, cookie=None, priority=None, reason=None, table_id=None, duration_sec=None, duration_nsec=None, idle_timeout=None, packet_count=None, byte_count=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_removed()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        reader.skip(2)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.priority != other.priority: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_removed {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[11] = flow_removed
+
+class flow_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.flow_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[1] = flow_stats_reply
+
+class flow_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[1] = flow_stats_request
+
+class get_config_reply(message):
+    version = 2
+    type = 8
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[8] = get_config_reply
+
+class get_config_request(message):
+    version = 2
+    type = 7
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[7] = get_config_request
+
+class group_mod(message):
+    subtypes = {}
+
+    version = 2
+    type = 15
+
+    def __init__(self, xid=None, command=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if command != None:
+            self.command = command
+        else:
+            self.command = 0
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = group_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = group_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.command = reader.read("!H")[0]
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.command != other.command: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[15] = group_mod
+
+class group_add(group_mod):
+    version = 2
+    type = 15
+    command = 0
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 0)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[0] = group_add
+
+class group_delete(group_mod):
+    version = 2
+    type = 15
+    command = 2
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[2] = group_delete
+
+class group_desc_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[7] = group_desc_stats_reply
+
+class group_desc_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[7] = group_desc_stats_request
+
+class group_mod_failed_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 6
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 6)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[6] = group_mod_failed_error_msg
+
+class group_modify(group_mod):
+    version = 2
+    type = 15
+    command = 1
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 1)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[1] = group_modify
+
+class group_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[6] = group_stats_reply
+
+class group_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, group_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.group_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[6] = group_stats_request
+
+class hello(message):
+    version = 2
+    type = 0
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[0] = hello
+
+class hello_failed_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 0
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 0)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[0] = hello_failed_error_msg
+
+class nicira_header(experimenter):
+    subtypes = {}
+
+    version = 2
+    type = 4
+    experimenter = 8992
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = nicira_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira_header
+
+class packet_in(message):
+    version = 2
+    type = 10
+
+    def __init__(self, xid=None, buffer_id=None, in_port=None, in_phy_port=None, total_len=None, reason=None, table_id=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if in_phy_port != None:
+            self.in_phy_port = in_phy_port
+        else:
+            self.in_phy_port = 0
+        if total_len != None:
+            self.total_len = total_len
+        else:
+            self.total_len = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(util.pack_port_no(self.in_phy_port))
+        packed.append(struct.pack("!H", self.total_len))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_in()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.in_port = util.unpack_port_no(reader)
+        obj.in_phy_port = util.unpack_port_no(reader)
+        obj.total_len = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.in_port != other.in_port: return False
+        if self.in_phy_port != other.in_phy_port: return False
+        if self.total_len != other.total_len: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("in_phy_port = ");
+                q.text(util.pretty_port(self.in_phy_port))
+                q.text(","); q.breakable()
+                q.text("total_len = ");
+                q.text("%#x" % self.total_len)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[10] = packet_in
+
+class packet_out(message):
+    version = 2
+    type = 13
+
+    def __init__(self, xid=None, buffer_id=None, in_port=None, actions=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(struct.pack("!H", 0)) # placeholder for actions_len at index 6
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        packed[6] = struct.pack("!H", len(packed[-1]))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_out()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.in_port = util.unpack_port_no(reader)
+        _actions_len = reader.read("!H")[0]
+        reader.skip(6)
+        obj.actions = loxi.generic_util.unpack_list(reader.slice(_actions_len), ofp.action.action.unpack)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.in_port != other.in_port: return False
+        if self.actions != other.actions: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[13] = packet_out
+
+class port_mod(message):
+    version = 2
+    type = 16
+
+    def __init__(self, xid=None, port_no=None, hw_addr=None, config=None, mask=None, advertise=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        if advertise != None:
+            self.advertise = advertise
+        else:
+            self.advertise = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.mask))
+        packed.append(struct.pack("!L", self.advertise))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.config = reader.read("!L")[0]
+        obj.mask = reader.read("!L")[0]
+        obj.advertise = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.config != other.config: return False
+        if self.mask != other.mask: return False
+        if self.advertise != other.advertise: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+                q.text(","); q.breakable()
+                q.text("advertise = ");
+                q.text("%#x" % self.advertise)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[16] = port_mod
+
+class port_mod_failed_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 7
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 7)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[7] = port_mod_failed_error_msg
+
+class port_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.port_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[4] = port_stats_reply
+
+class port_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[4] = port_stats_request
+
+class port_status(message):
+    version = 2
+    type = 12
+
+    def __init__(self, xid=None, reason=None, desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if desc != None:
+            self.desc = desc
+        else:
+            self.desc = ofp.port_desc()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 7)
+        packed.append(self.desc.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(7)
+        obj.desc = ofp.port_desc.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.reason != other.reason: return False
+        if self.desc != other.desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("desc = ");
+                q.pp(self.desc)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[12] = port_status
+
+class queue_get_config_reply(message):
+    version = 2
+    type = 23
+
+    def __init__(self, xid=None, port=None, queues=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if queues != None:
+            self.queues = queues
+        else:
+            self.queues = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.queues))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 23)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.queues = loxi.generic_util.unpack_list(reader, ofp.common.packet_queue.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        if self.queues != other.queues: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("queues = ");
+                q.pp(self.queues)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[23] = queue_get_config_reply
+
+class queue_get_config_request(message):
+    version = 2
+    type = 22
+
+    def __init__(self, xid=None, port=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 22)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+            q.breakable()
+        q.text('}')
+
+message.subtypes[22] = queue_get_config_request
+
+class queue_op_failed_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 9
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_op_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 9)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_op_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[9] = queue_op_failed_error_msg
+
+class queue_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.queue_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[5] = queue_stats_reply
+
+class queue_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, port_no=None, queue_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[5] = queue_stats_request
+
+class set_config(message):
+    version = 2
+    type = 9
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_config()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_config {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[9] = set_config
+
+class switch_config_failed_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 10
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = switch_config_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 10)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("switch_config_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[10] = switch_config_failed_error_msg
+
+class table_mod(message):
+    version = 2
+    type = 17
+
+    def __init__(self, xid=None, table_id=None, config=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.config))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.config = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.config != other.config: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[17] = table_mod
+
+class table_mod_failed_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 8
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 8)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[8] = table_mod_failed_error_msg
+
+class table_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[3] = table_stats_reply
+
+class table_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[3] = table_stats_request
+
+
+def parse_header(buf):
+    if len(buf) < 8:
+        raise loxi.ProtocolError("too short to be an OpenFlow message")
+    return struct.unpack_from("!BBHL", buf)
+
+def parse_message(buf):
+    msg_ver, msg_type, msg_len, msg_xid = parse_header(buf)
+    if msg_ver != ofp.OFP_VERSION and msg_type != ofp.OFPT_HELLO:
+        raise loxi.ProtocolError("wrong OpenFlow version (expected %d, got %d)" % (ofp.OFP_VERSION, msg_ver))
+    if len(buf) != msg_len:
+        raise loxi.ProtocolError("incorrect message size")
+    return message.unpack(loxi.generic_util.OFReader(buf))
diff --git a/Fabric/Utilities/src/python/loxi/of11/util.py b/Fabric/Utilities/src/python/loxi/of11/util.py
new file mode 100644
index 0000000..b5142a8
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of11/util.py
@@ -0,0 +1,143 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+# Automatically generated by LOXI from template util.py
+# Do not modify
+
+import struct
+import loxi
+import const
+import common
+import action
+import instruction
+
+def pretty_mac(mac):
+    return ':'.join(["%02x" % x for x in mac])
+
+def pretty_ipv4(v):
+    return "%d.%d.%d.%d" % ((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF)
+
+def pretty_flags(v, flag_names):
+    set_flags = []
+    for flag_name in flag_names:
+        flag_value = getattr(const, flag_name)
+        if v & flag_value == flag_value:
+            set_flags.append(flag_name)
+        elif v & flag_value:
+            set_flags.append('%s&%#x' % (flag_name, v & flag_value))
+        v &= ~flag_value
+    if v:
+        set_flags.append("%#x" % v)
+    return '|'.join(set_flags) or '0'
+
+def pretty_wildcards(v):
+    if v == const.OFPFW_ALL:
+        return 'OFPFW_ALL'
+    flag_names = ['OFPFW_IN_PORT', 'OFPFW_DL_VLAN', 'OFPFW_DL_SRC', 'OFPFW_DL_DST',
+                  'OFPFW_DL_TYPE', 'OFPFW_NW_PROTO', 'OFPFW_TP_SRC', 'OFPFW_TP_DST',
+                  'OFPFW_NW_SRC_MASK', 'OFPFW_NW_DST_MASK', 'OFPFW_DL_VLAN_PCP',
+                  'OFPFW_NW_TOS']
+    return pretty_flags(v, flag_names)
+
+def pretty_port(v):
+    named_ports = [(k,v2) for (k,v2) in const.__dict__.iteritems() if k.startswith('OFPP_')]
+    for (k, v2) in named_ports:
+        if v == v2:
+            return k
+    return v
+
+def pack_port_no(value):
+    return struct.pack("!L", value)
+
+def unpack_port_no(reader):
+    return reader.read("!L")[0]
+
+def pack_fm_cmd(value):
+    return struct.pack("!B", value)
+
+def unpack_fm_cmd(reader):
+    return reader.read("!B")[0]
+
+def init_wc_bmap():
+    return const.OFPFW_ALL
+
+def pack_wc_bmap(value):
+    return struct.pack("!L", value)
+
+def unpack_wc_bmap(reader):
+    return reader.read("!L")[0]
+
+def init_match_bmap():
+    return const.OFPFW_ALL
+
+def pack_match_bmap(value):
+    return struct.pack("!L", value)
+
+def unpack_match_bmap(reader):
+    return reader.read("!L")[0]
+
+MASK64 = (1 << 64) - 1
+
+def pack_bitmap_128(value):
+    x = 0l
+    for y in value:
+        x |= 1 << y
+    return struct.pack("!QQ", (x >> 64) & MASK64, x & MASK64)
+
+def unpack_bitmap_128(reader):
+    hi, lo = reader.read("!QQ")
+    x = (hi << 64) | lo
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_bitmap_512(value):
+    words = [0] * 8
+    for v in value:
+        assert v < 512
+        words[7-v/64] |= 1 << (v % 64)
+    return struct.pack("!8Q", *words)
+
+def unpack_bitmap_512(reader):
+    words = reader.read("!8Q")
+    x = 0l
+    for word in words:
+        x <<= 64
+        x |= word
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_checksum_128(value):
+    return struct.pack("!QQ", (value >> 64) & MASK64, value & MASK64)
+
+def unpack_checksum_128(reader):
+    hi, lo = reader.read("!QQ")
+    return (hi << 64) | lo
diff --git a/Fabric/Utilities/src/python/loxi/of12/__init__.py b/Fabric/Utilities/src/python/loxi/of12/__init__.py
new file mode 100644
index 0000000..a994272
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/__init__.py
@@ -0,0 +1,33 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template init.py
+# Do not modify
+
+import const
+import action
+import oxm
+import message
+import instruction
+import common
+from const import *
+from common import *
+from loxi import ProtocolError
diff --git a/Fabric/Utilities/src/python/loxi/of12/action.py b/Fabric/Utilities/src/python/loxi/of12/action.py
new file mode 100644
index 0000000..261170a
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/action.py
@@ -0,0 +1,1147 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of12']
+
+class action(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = action.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = action()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("action {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(action):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed.append(loxi.generic_util.pad_to(8, length))
+        length += len(packed[-1])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_checksum(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_checksum_128(self.checksum))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_checksum()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_checksum {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_checksum
+
+class bsn_mirror(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, dest_port=None, vlan_tag=None, copy_stage=None):
+        if dest_port != None:
+            self.dest_port = dest_port
+        else:
+            self.dest_port = 0
+        if vlan_tag != None:
+            self.vlan_tag = vlan_tag
+        else:
+            self.vlan_tag = 0
+        if copy_stage != None:
+            self.copy_stage = copy_stage
+        else:
+            self.copy_stage = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dest_port))
+        packed.append(struct.pack("!L", self.vlan_tag))
+        packed.append(struct.pack("!B", self.copy_stage))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_mirror()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.dest_port = reader.read("!L")[0]
+        obj.vlan_tag = reader.read("!L")[0]
+        obj.copy_stage = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dest_port != other.dest_port: return False
+        if self.vlan_tag != other.vlan_tag: return False
+        if self.copy_stage != other.copy_stage: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_mirror {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dest_port = ");
+                q.text("%#x" % self.dest_port)
+                q.text(","); q.breakable()
+                q.text("vlan_tag = ");
+                q.text("%#x" % self.vlan_tag)
+                q.text(","); q.breakable()
+                q.text("copy_stage = ");
+                q.text("%#x" % self.copy_stage)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_mirror
+
+class bsn_set_tunnel_dst(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, dst=None):
+        if dst != None:
+            self.dst = dst
+        else:
+            self.dst = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dst))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_tunnel_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.dst = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dst != other.dst: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_tunnel_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dst = ");
+                q.text("%#x" % self.dst)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_set_tunnel_dst
+
+class copy_ttl_in(action):
+    type = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_in()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[12] = copy_ttl_in
+
+class copy_ttl_out(action):
+    type = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_out()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[11] = copy_ttl_out
+
+class dec_mpls_ttl(action):
+    type = 16
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[16] = dec_mpls_ttl
+
+class dec_nw_ttl(action):
+    type = 24
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[24] = dec_nw_ttl
+
+class group(action):
+    type = 22
+
+    def __init__(self, group_id=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.group_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.group_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[22] = group
+
+class nicira(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 8992
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = nicira.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!H")[0]
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira
+
+class nicira_dec_ttl(nicira):
+    type = 65535
+    experimenter = 8992
+    subtype = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_dec_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == 18)
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_dec_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+nicira.subtypes[18] = nicira_dec_ttl
+
+class output(action):
+    type = 0
+
+    def __init__(self, port=None, max_len=None):
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if max_len != None:
+            self.max_len = max_len
+        else:
+            self.max_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", self.max_len))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = output()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.port = util.unpack_port_no(reader)
+        obj.max_len = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port != other.port: return False
+        if self.max_len != other.max_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("max_len = ");
+                q.text("%#x" % self.max_len)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[0] = output
+
+class pop_mpls(action):
+    type = 20
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[20] = pop_mpls
+
+class pop_vlan(action):
+    type = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[18] = pop_vlan
+
+class push_mpls(action):
+    type = 19
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[19] = push_mpls
+
+class push_vlan(action):
+    type = 17
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[17] = push_vlan
+
+class set_field(action):
+    type = 25
+
+    def __init__(self, field=None):
+        if field != None:
+            self.field = field
+        else:
+            self.field = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(self.field.pack())
+        length = sum([len(x) for x in packed])
+        packed.append(loxi.generic_util.pad_to(8, length))
+        length += len(packed[-1])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_field()
+        _type = reader.read("!H")[0]
+        assert(_type == 25)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.field = ofp.oxm.oxm.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.field != other.field: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_field {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("field = ");
+                q.pp(self.field)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[25] = set_field
+
+class set_mpls_ttl(action):
+    type = 15
+
+    def __init__(self, mpls_ttl=None):
+        if mpls_ttl != None:
+            self.mpls_ttl = mpls_ttl
+        else:
+            self.mpls_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.mpls_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.mpls_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mpls_ttl != other.mpls_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mpls_ttl = ");
+                q.text("%#x" % self.mpls_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[15] = set_mpls_ttl
+
+class set_nw_ttl(action):
+    type = 23
+
+    def __init__(self, nw_ttl=None):
+        if nw_ttl != None:
+            self.nw_ttl = nw_ttl
+        else:
+            self.nw_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.nw_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_ttl != other.nw_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_ttl = ");
+                q.text("%#x" % self.nw_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[23] = set_nw_ttl
+
+class set_queue(action):
+    type = 21
+
+    def __init__(self, queue_id=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_queue()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[21] = set_queue
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of12/common.py b/Fabric/Utilities/src/python/loxi/of12/common.py
new file mode 100644
index 0000000..64e8379
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/common.py
@@ -0,0 +1,1711 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of12']
+
+class bsn_interface(loxi.OFObject):
+
+    def __init__(self, hw_addr=None, name=None, ipv4_addr=None, ipv4_netmask=None):
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if ipv4_addr != None:
+            self.ipv4_addr = ipv4_addr
+        else:
+            self.ipv4_addr = 0
+        if ipv4_netmask != None:
+            self.ipv4_netmask = ipv4_netmask
+        else:
+            self.ipv4_netmask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.ipv4_addr))
+        packed.append(struct.pack("!L", self.ipv4_netmask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_interface()
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.ipv4_addr = reader.read("!L")[0]
+        obj.ipv4_netmask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.ipv4_addr != other.ipv4_addr: return False
+        if self.ipv4_netmask != other.ipv4_netmask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_interface {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("ipv4_addr = ");
+                q.text(util.pretty_ipv4(self.ipv4_addr))
+                q.text(","); q.breakable()
+                q.text("ipv4_netmask = ");
+                q.text(util.pretty_ipv4(self.ipv4_netmask))
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bsn_vport.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_vport()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport_l2gre(bsn_vport):
+    type = 1
+
+    def __init__(self, flags=None, port_no=None, loopback_port_no=None, local_mac=None, nh_mac=None, src_ip=None, dst_ip=None, dscp=None, ttl=None, vpn=None, rate_limit=None, if_name=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if loopback_port_no != None:
+            self.loopback_port_no = loopback_port_no
+        else:
+            self.loopback_port_no = 0
+        if local_mac != None:
+            self.local_mac = local_mac
+        else:
+            self.local_mac = [0,0,0,0,0,0]
+        if nh_mac != None:
+            self.nh_mac = nh_mac
+        else:
+            self.nh_mac = [0,0,0,0,0,0]
+        if src_ip != None:
+            self.src_ip = src_ip
+        else:
+            self.src_ip = 0
+        if dst_ip != None:
+            self.dst_ip = dst_ip
+        else:
+            self.dst_ip = 0
+        if dscp != None:
+            self.dscp = dscp
+        else:
+            self.dscp = 0
+        if ttl != None:
+            self.ttl = ttl
+        else:
+            self.ttl = 0
+        if vpn != None:
+            self.vpn = vpn
+        else:
+            self.vpn = 0
+        if rate_limit != None:
+            self.rate_limit = rate_limit
+        else:
+            self.rate_limit = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.flags))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(util.pack_port_no(self.loopback_port_no))
+        packed.append(struct.pack("!6B", *self.local_mac))
+        packed.append(struct.pack("!6B", *self.nh_mac))
+        packed.append(struct.pack("!L", self.src_ip))
+        packed.append(struct.pack("!L", self.dst_ip))
+        packed.append(struct.pack("!B", self.dscp))
+        packed.append(struct.pack("!B", self.ttl))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.vpn))
+        packed.append(struct.pack("!L", self.rate_limit))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_l2gre()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.flags = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.loopback_port_no = util.unpack_port_no(reader)
+        obj.local_mac = list(reader.read('!6B'))
+        obj.nh_mac = list(reader.read('!6B'))
+        obj.src_ip = reader.read("!L")[0]
+        obj.dst_ip = reader.read("!L")[0]
+        obj.dscp = reader.read("!B")[0]
+        obj.ttl = reader.read("!B")[0]
+        reader.skip(2)
+        obj.vpn = reader.read("!L")[0]
+        obj.rate_limit = reader.read("!L")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.loopback_port_no != other.loopback_port_no: return False
+        if self.local_mac != other.local_mac: return False
+        if self.nh_mac != other.nh_mac: return False
+        if self.src_ip != other.src_ip: return False
+        if self.dst_ip != other.dst_ip: return False
+        if self.dscp != other.dscp: return False
+        if self.ttl != other.ttl: return False
+        if self.vpn != other.vpn: return False
+        if self.rate_limit != other.rate_limit: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_l2gre {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("loopback_port_no = ");
+                q.text(util.pretty_port(self.loopback_port_no))
+                q.text(","); q.breakable()
+                q.text("local_mac = ");
+                q.text(util.pretty_mac(self.local_mac))
+                q.text(","); q.breakable()
+                q.text("nh_mac = ");
+                q.text(util.pretty_mac(self.nh_mac))
+                q.text(","); q.breakable()
+                q.text("src_ip = ");
+                q.text(util.pretty_ipv4(self.src_ip))
+                q.text(","); q.breakable()
+                q.text("dst_ip = ");
+                q.text(util.pretty_ipv4(self.dst_ip))
+                q.text(","); q.breakable()
+                q.text("dscp = ");
+                q.text("%#x" % self.dscp)
+                q.text(","); q.breakable()
+                q.text("ttl = ");
+                q.text("%#x" % self.ttl)
+                q.text(","); q.breakable()
+                q.text("vpn = ");
+                q.text("%#x" % self.vpn)
+                q.text(","); q.breakable()
+                q.text("rate_limit = ");
+                q.text("%#x" % self.rate_limit)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[1] = bsn_vport_l2gre
+
+class bsn_vport_q_in_q(bsn_vport):
+    type = 0
+
+    def __init__(self, port_no=None, ingress_tpid=None, ingress_vlan_id=None, egress_tpid=None, egress_vlan_id=None, if_name=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if ingress_tpid != None:
+            self.ingress_tpid = ingress_tpid
+        else:
+            self.ingress_tpid = 0
+        if ingress_vlan_id != None:
+            self.ingress_vlan_id = ingress_vlan_id
+        else:
+            self.ingress_vlan_id = 0
+        if egress_tpid != None:
+            self.egress_tpid = egress_tpid
+        else:
+            self.egress_tpid = 0
+        if egress_vlan_id != None:
+            self.egress_vlan_id = egress_vlan_id
+        else:
+            self.egress_vlan_id = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.port_no))
+        packed.append(struct.pack("!H", self.ingress_tpid))
+        packed.append(struct.pack("!H", self.ingress_vlan_id))
+        packed.append(struct.pack("!H", self.egress_tpid))
+        packed.append(struct.pack("!H", self.egress_vlan_id))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_q_in_q()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.port_no = reader.read("!L")[0]
+        obj.ingress_tpid = reader.read("!H")[0]
+        obj.ingress_vlan_id = reader.read("!H")[0]
+        obj.egress_tpid = reader.read("!H")[0]
+        obj.egress_vlan_id = reader.read("!H")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.ingress_tpid != other.ingress_tpid: return False
+        if self.ingress_vlan_id != other.ingress_vlan_id: return False
+        if self.egress_tpid != other.egress_tpid: return False
+        if self.egress_vlan_id != other.egress_vlan_id: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_q_in_q {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text("%#x" % self.port_no)
+                q.text(","); q.breakable()
+                q.text("ingress_tpid = ");
+                q.text("%#x" % self.ingress_tpid)
+                q.text(","); q.breakable()
+                q.text("ingress_vlan_id = ");
+                q.text("%#x" % self.ingress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("egress_tpid = ");
+                q.text("%#x" % self.egress_tpid)
+                q.text(","); q.breakable()
+                q.text("egress_vlan_id = ");
+                q.text("%#x" % self.egress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[0] = bsn_vport_q_in_q
+
+class bucket(loxi.OFObject):
+
+    def __init__(self, weight=None, watch_port=None, watch_group=None, actions=None):
+        if weight != None:
+            self.weight = weight
+        else:
+            self.weight = 0
+        if watch_port != None:
+            self.watch_port = watch_port
+        else:
+            self.watch_port = 0
+        if watch_group != None:
+            self.watch_group = watch_group
+        else:
+            self.watch_group = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 0
+        packed.append(struct.pack("!H", self.weight))
+        packed.append(util.pack_port_no(self.watch_port))
+        packed.append(struct.pack("!L", self.watch_group))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket()
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 2)
+        obj.weight = reader.read("!H")[0]
+        obj.watch_port = util.unpack_port_no(reader)
+        obj.watch_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.weight != other.weight: return False
+        if self.watch_port != other.watch_port: return False
+        if self.watch_group != other.watch_group: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("weight = ");
+                q.text("%#x" % self.weight)
+                q.text(","); q.breakable()
+                q.text("watch_port = ");
+                q.text(util.pretty_port(self.watch_port))
+                q.text(","); q.breakable()
+                q.text("watch_group = ");
+                q.text("%#x" % self.watch_group)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+
+class bucket_counter(loxi.OFObject):
+
+    def __init__(self, packet_count=None, byte_count=None):
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket_counter()
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket_counter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+            q.breakable()
+        q.text('}')
+
+
+class flow_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, duration_sec=None, duration_nsec=None, priority=None, idle_timeout=None, hard_timeout=None, cookie=None, packet_count=None, byte_count=None, match=None, instructions=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append('\x00' * 6)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        reader.skip(6)
+        obj.cookie = reader.read("!Q")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.priority != other.priority: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.cookie != other.cookie: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+
+class group_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_type=None, group_id=None, buckets=None):
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+
+class group_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_id=None, ref_count=None, packet_count=None, byte_count=None, bucket_stats=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if ref_count != None:
+            self.ref_count = ref_count
+        else:
+            self.ref_count = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if bucket_stats != None:
+            self.bucket_stats = bucket_stats
+        else:
+            self.bucket_stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(struct.pack("!L", self.ref_count))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(loxi.generic_util.pack_list(self.bucket_stats))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.group_id = reader.read("!L")[0]
+        obj.ref_count = reader.read("!L")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.bucket_stats = loxi.generic_util.unpack_list(reader, ofp.common.bucket_counter.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        if self.ref_count != other.ref_count: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.bucket_stats != other.bucket_stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("ref_count = ");
+                q.text("%#x" % self.ref_count)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("bucket_stats = ");
+                q.pp(self.bucket_stats)
+            q.breakable()
+        q.text('}')
+
+
+class match_v3(loxi.OFObject):
+    type = 1
+
+    def __init__(self, oxm_list=None):
+        if oxm_list != None:
+            self.oxm_list = oxm_list
+        else:
+            self.oxm_list = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_list))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = match_v3()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_list = loxi.generic_util.unpack_list(reader, ofp.oxm.oxm.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_list != other.oxm_list: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("match_v3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_list = ");
+                q.pp(self.oxm_list)
+            q.breakable()
+        q.text('}')
+
+
+class packet_queue(loxi.OFObject):
+
+    def __init__(self, queue_id=None, port=None, properties=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 2
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_queue()
+        obj.queue_id = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 10)
+        reader.skip(6)
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.common.queue_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        if self.port != other.port: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class port_desc(loxi.OFObject):
+
+    def __init__(self, port_no=None, hw_addr=None, name=None, config=None, state=None, curr=None, advertised=None, supported=None, peer=None, curr_speed=None, max_speed=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if state != None:
+            self.state = state
+        else:
+            self.state = 0
+        if curr != None:
+            self.curr = curr
+        else:
+            self.curr = 0
+        if advertised != None:
+            self.advertised = advertised
+        else:
+            self.advertised = 0
+        if supported != None:
+            self.supported = supported
+        else:
+            self.supported = 0
+        if peer != None:
+            self.peer = peer
+        else:
+            self.peer = 0
+        if curr_speed != None:
+            self.curr_speed = curr_speed
+        else:
+            self.curr_speed = 0
+        if max_speed != None:
+            self.max_speed = max_speed
+        else:
+            self.max_speed = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.state))
+        packed.append(struct.pack("!L", self.curr))
+        packed.append(struct.pack("!L", self.advertised))
+        packed.append(struct.pack("!L", self.supported))
+        packed.append(struct.pack("!L", self.peer))
+        packed.append(struct.pack("!L", self.curr_speed))
+        packed.append(struct.pack("!L", self.max_speed))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.config = reader.read("!L")[0]
+        obj.state = reader.read("!L")[0]
+        obj.curr = reader.read("!L")[0]
+        obj.advertised = reader.read("!L")[0]
+        obj.supported = reader.read("!L")[0]
+        obj.peer = reader.read("!L")[0]
+        obj.curr_speed = reader.read("!L")[0]
+        obj.max_speed = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.config != other.config: return False
+        if self.state != other.state: return False
+        if self.curr != other.curr: return False
+        if self.advertised != other.advertised: return False
+        if self.supported != other.supported: return False
+        if self.peer != other.peer: return False
+        if self.curr_speed != other.curr_speed: return False
+        if self.max_speed != other.max_speed: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("state = ");
+                q.text("%#x" % self.state)
+                q.text(","); q.breakable()
+                q.text("curr = ");
+                q.text("%#x" % self.curr)
+                q.text(","); q.breakable()
+                q.text("advertised = ");
+                q.text("%#x" % self.advertised)
+                q.text(","); q.breakable()
+                q.text("supported = ");
+                q.text("%#x" % self.supported)
+                q.text(","); q.breakable()
+                q.text("peer = ");
+                q.text("%#x" % self.peer)
+                q.text(","); q.breakable()
+                q.text("curr_speed = ");
+                q.text("%#x" % self.curr_speed)
+                q.text(","); q.breakable()
+                q.text("max_speed = ");
+                q.text("%#x" % self.max_speed)
+            q.breakable()
+        q.text('}')
+
+
+class port_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, rx_packets=None, tx_packets=None, rx_bytes=None, tx_bytes=None, rx_dropped=None, tx_dropped=None, rx_errors=None, tx_errors=None, rx_frame_err=None, rx_over_err=None, rx_crc_err=None, collisions=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if rx_packets != None:
+            self.rx_packets = rx_packets
+        else:
+            self.rx_packets = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if rx_bytes != None:
+            self.rx_bytes = rx_bytes
+        else:
+            self.rx_bytes = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if rx_dropped != None:
+            self.rx_dropped = rx_dropped
+        else:
+            self.rx_dropped = 0
+        if tx_dropped != None:
+            self.tx_dropped = tx_dropped
+        else:
+            self.tx_dropped = 0
+        if rx_errors != None:
+            self.rx_errors = rx_errors
+        else:
+            self.rx_errors = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        if rx_frame_err != None:
+            self.rx_frame_err = rx_frame_err
+        else:
+            self.rx_frame_err = 0
+        if rx_over_err != None:
+            self.rx_over_err = rx_over_err
+        else:
+            self.rx_over_err = 0
+        if rx_crc_err != None:
+            self.rx_crc_err = rx_crc_err
+        else:
+            self.rx_crc_err = 0
+        if collisions != None:
+            self.collisions = collisions
+        else:
+            self.collisions = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.rx_packets))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.rx_bytes))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.rx_dropped))
+        packed.append(struct.pack("!Q", self.tx_dropped))
+        packed.append(struct.pack("!Q", self.rx_errors))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        packed.append(struct.pack("!Q", self.rx_frame_err))
+        packed.append(struct.pack("!Q", self.rx_over_err))
+        packed.append(struct.pack("!Q", self.rx_crc_err))
+        packed.append(struct.pack("!Q", self.collisions))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.rx_packets = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.rx_bytes = reader.read("!Q")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.rx_dropped = reader.read("!Q")[0]
+        obj.tx_dropped = reader.read("!Q")[0]
+        obj.rx_errors = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        obj.rx_frame_err = reader.read("!Q")[0]
+        obj.rx_over_err = reader.read("!Q")[0]
+        obj.rx_crc_err = reader.read("!Q")[0]
+        obj.collisions = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.rx_packets != other.rx_packets: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.rx_bytes != other.rx_bytes: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.rx_dropped != other.rx_dropped: return False
+        if self.tx_dropped != other.tx_dropped: return False
+        if self.rx_errors != other.rx_errors: return False
+        if self.tx_errors != other.tx_errors: return False
+        if self.rx_frame_err != other.rx_frame_err: return False
+        if self.rx_over_err != other.rx_over_err: return False
+        if self.rx_crc_err != other.rx_crc_err: return False
+        if self.collisions != other.collisions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("rx_packets = ");
+                q.text("%#x" % self.rx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("rx_bytes = ");
+                q.text("%#x" % self.rx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("rx_dropped = ");
+                q.text("%#x" % self.rx_dropped)
+                q.text(","); q.breakable()
+                q.text("tx_dropped = ");
+                q.text("%#x" % self.tx_dropped)
+                q.text(","); q.breakable()
+                q.text("rx_errors = ");
+                q.text("%#x" % self.rx_errors)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+                q.text(","); q.breakable()
+                q.text("rx_frame_err = ");
+                q.text("%#x" % self.rx_frame_err)
+                q.text(","); q.breakable()
+                q.text("rx_over_err = ");
+                q.text("%#x" % self.rx_over_err)
+                q.text(","); q.breakable()
+                q.text("rx_crc_err = ");
+                q.text("%#x" % self.rx_crc_err)
+                q.text(","); q.breakable()
+                q.text("collisions = ");
+                q.text("%#x" % self.collisions)
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = queue_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop_experimenter(queue_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append('\x00' * 4)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = queue_prop_experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop_experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        reader.skip(4)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[65535] = queue_prop_experimenter
+
+class queue_prop_max_rate(queue_prop):
+    type = 2
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_max_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_max_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[2] = queue_prop_max_rate
+
+class queue_prop_min_rate(queue_prop):
+    type = 1
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_min_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_min_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[1] = queue_prop_min_rate
+
+class queue_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, queue_id=None, tx_bytes=None, tx_packets=None, tx_errors=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.tx_errors != other.tx_errors: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+            q.breakable()
+        q.text('}')
+
+
+class table_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, name=None, match=None, wildcards=None, write_actions=None, apply_actions=None, write_setfields=None, apply_setfields=None, metadata_match=None, metadata_write=None, instructions=None, config=None, max_entries=None, active_count=None, lookup_count=None, matched_count=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if match != None:
+            self.match = match
+        else:
+            self.match = util.init_match_bmap()
+        if wildcards != None:
+            self.wildcards = wildcards
+        else:
+            self.wildcards = util.init_wc_bmap()
+        if write_actions != None:
+            self.write_actions = write_actions
+        else:
+            self.write_actions = 0
+        if apply_actions != None:
+            self.apply_actions = apply_actions
+        else:
+            self.apply_actions = 0
+        if write_setfields != None:
+            self.write_setfields = write_setfields
+        else:
+            self.write_setfields = 0
+        if apply_setfields != None:
+            self.apply_setfields = apply_setfields
+        else:
+            self.apply_setfields = 0
+        if metadata_match != None:
+            self.metadata_match = metadata_match
+        else:
+            self.metadata_match = 0
+        if metadata_write != None:
+            self.metadata_write = metadata_write
+        else:
+            self.metadata_write = 0
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if max_entries != None:
+            self.max_entries = max_entries
+        else:
+            self.max_entries = 0
+        if active_count != None:
+            self.active_count = active_count
+        else:
+            self.active_count = 0
+        if lookup_count != None:
+            self.lookup_count = lookup_count
+        else:
+            self.lookup_count = 0
+        if matched_count != None:
+            self.matched_count = matched_count
+        else:
+            self.matched_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 7)
+        packed.append(struct.pack("!32s", self.name))
+        packed.append(util.pack_match_bmap(self.match))
+        packed.append(util.pack_wc_bmap(self.wildcards))
+        packed.append(struct.pack("!L", self.write_actions))
+        packed.append(struct.pack("!L", self.apply_actions))
+        packed.append(struct.pack("!Q", self.write_setfields))
+        packed.append(struct.pack("!Q", self.apply_setfields))
+        packed.append(struct.pack("!Q", self.metadata_match))
+        packed.append(struct.pack("!Q", self.metadata_write))
+        packed.append(struct.pack("!L", self.instructions))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.max_entries))
+        packed.append(struct.pack("!L", self.active_count))
+        packed.append(struct.pack("!Q", self.lookup_count))
+        packed.append(struct.pack("!Q", self.matched_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_entry()
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(7)
+        obj.name = reader.read("!32s")[0].rstrip("\x00")
+        obj.match = util.unpack_match_bmap(reader)
+        obj.wildcards = util.unpack_wc_bmap(reader)
+        obj.write_actions = reader.read("!L")[0]
+        obj.apply_actions = reader.read("!L")[0]
+        obj.write_setfields = reader.read("!Q")[0]
+        obj.apply_setfields = reader.read("!Q")[0]
+        obj.metadata_match = reader.read("!Q")[0]
+        obj.metadata_write = reader.read("!Q")[0]
+        obj.instructions = reader.read("!L")[0]
+        obj.config = reader.read("!L")[0]
+        obj.max_entries = reader.read("!L")[0]
+        obj.active_count = reader.read("!L")[0]
+        obj.lookup_count = reader.read("!Q")[0]
+        obj.matched_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.name != other.name: return False
+        if self.match != other.match: return False
+        if self.wildcards != other.wildcards: return False
+        if self.write_actions != other.write_actions: return False
+        if self.apply_actions != other.apply_actions: return False
+        if self.write_setfields != other.write_setfields: return False
+        if self.apply_setfields != other.apply_setfields: return False
+        if self.metadata_match != other.metadata_match: return False
+        if self.metadata_write != other.metadata_write: return False
+        if self.instructions != other.instructions: return False
+        if self.config != other.config: return False
+        if self.max_entries != other.max_entries: return False
+        if self.active_count != other.active_count: return False
+        if self.lookup_count != other.lookup_count: return False
+        if self.matched_count != other.matched_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("wildcards = ");
+                q.pp(self.wildcards)
+                q.text(","); q.breakable()
+                q.text("write_actions = ");
+                q.text("%#x" % self.write_actions)
+                q.text(","); q.breakable()
+                q.text("apply_actions = ");
+                q.text("%#x" % self.apply_actions)
+                q.text(","); q.breakable()
+                q.text("write_setfields = ");
+                q.text("%#x" % self.write_setfields)
+                q.text(","); q.breakable()
+                q.text("apply_setfields = ");
+                q.text("%#x" % self.apply_setfields)
+                q.text(","); q.breakable()
+                q.text("metadata_match = ");
+                q.text("%#x" % self.metadata_match)
+                q.text(","); q.breakable()
+                q.text("metadata_write = ");
+                q.text("%#x" % self.metadata_write)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.text("%#x" % self.instructions)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("max_entries = ");
+                q.text("%#x" % self.max_entries)
+                q.text(","); q.breakable()
+                q.text("active_count = ");
+                q.text("%#x" % self.active_count)
+                q.text(","); q.breakable()
+                q.text("lookup_count = ");
+                q.text("%#x" % self.lookup_count)
+                q.text(","); q.breakable()
+                q.text("matched_count = ");
+                q.text("%#x" % self.matched_count)
+            q.breakable()
+        q.text('}')
+
+
+
+match = match_v3
diff --git a/Fabric/Utilities/src/python/loxi/of12/const.py b/Fabric/Utilities/src/python/loxi/of12/const.py
new file mode 100644
index 0000000..70a63f8
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/const.py
@@ -0,0 +1,840 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template const.py
+# Do not modify
+
+OFP_VERSION = 3
+
+# Identifiers from group macro_definitions
+OFP_MAX_TABLE_NAME_LEN = 32
+OFP_MAX_PORT_NAME_LEN = 16
+OFP_TCP_PORT = 6653
+OFP_SSL_PORT = 6653
+OFP_ETH_ALEN = 6
+OFP_DEFAULT_MISS_SEND_LEN = 128
+OFP_VLAN_NONE = 0
+OFP_FLOW_PERMANENT = 0
+OFP_DEFAULT_PRIORITY = 32768
+OFP_NO_BUFFER = 4294967295
+DESC_STR_LEN = 256
+SERIAL_NUM_LEN = 32
+OFPQ_ALL = 4294967295
+OFPQ_MIN_RATE_UNCFG = 65535
+OFPQ_MAX_RATE_UNCFG = 65535
+
+# Identifiers from group of_bsn_pdu_slot_num
+BSN_PDU_SLOT_NUM_ANY = 255
+
+of_bsn_pdu_slot_num_map = {
+    255: 'BSN_PDU_SLOT_NUM_ANY',
+}
+
+# Identifiers from group ofp_action_type
+OFPAT_OUTPUT = 0
+OFPAT_COPY_TTL_OUT = 11
+OFPAT_COPY_TTL_IN = 12
+OFPAT_SET_MPLS_TTL = 15
+OFPAT_DEC_MPLS_TTL = 16
+OFPAT_PUSH_VLAN = 17
+OFPAT_POP_VLAN = 18
+OFPAT_PUSH_MPLS = 19
+OFPAT_POP_MPLS = 20
+OFPAT_SET_QUEUE = 21
+OFPAT_GROUP = 22
+OFPAT_SET_NW_TTL = 23
+OFPAT_DEC_NW_TTL = 24
+OFPAT_SET_FIELD = 25
+OFPAT_EXPERIMENTER = 65535
+
+ofp_action_type_map = {
+    0: 'OFPAT_OUTPUT',
+    11: 'OFPAT_COPY_TTL_OUT',
+    12: 'OFPAT_COPY_TTL_IN',
+    15: 'OFPAT_SET_MPLS_TTL',
+    16: 'OFPAT_DEC_MPLS_TTL',
+    17: 'OFPAT_PUSH_VLAN',
+    18: 'OFPAT_POP_VLAN',
+    19: 'OFPAT_PUSH_MPLS',
+    20: 'OFPAT_POP_MPLS',
+    21: 'OFPAT_SET_QUEUE',
+    22: 'OFPAT_GROUP',
+    23: 'OFPAT_SET_NW_TTL',
+    24: 'OFPAT_DEC_NW_TTL',
+    25: 'OFPAT_SET_FIELD',
+    65535: 'OFPAT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_bad_action_code
+OFPBAC_BAD_TYPE = 0
+OFPBAC_BAD_LEN = 1
+OFPBAC_BAD_EXPERIMENTER = 2
+OFPBAC_BAD_EXPERIMENTER_TYPE = 3
+OFPBAC_BAD_OUT_PORT = 4
+OFPBAC_BAD_ARGUMENT = 5
+OFPBAC_EPERM = 6
+OFPBAC_TOO_MANY = 7
+OFPBAC_BAD_QUEUE = 8
+OFPBAC_BAD_OUT_GROUP = 9
+OFPBAC_MATCH_INCONSISTENT = 10
+OFPBAC_UNSUPPORTED_ORDER = 11
+OFPBAC_BAD_TAG = 12
+OFPBAC_BAD_SET_TYPE = 13
+OFPBAC_BAD_SET_LEN = 14
+OFPBAC_BAD_SET_ARGUMENT = 15
+
+ofp_bad_action_code_map = {
+    0: 'OFPBAC_BAD_TYPE',
+    1: 'OFPBAC_BAD_LEN',
+    2: 'OFPBAC_BAD_EXPERIMENTER',
+    3: 'OFPBAC_BAD_EXPERIMENTER_TYPE',
+    4: 'OFPBAC_BAD_OUT_PORT',
+    5: 'OFPBAC_BAD_ARGUMENT',
+    6: 'OFPBAC_EPERM',
+    7: 'OFPBAC_TOO_MANY',
+    8: 'OFPBAC_BAD_QUEUE',
+    9: 'OFPBAC_BAD_OUT_GROUP',
+    10: 'OFPBAC_MATCH_INCONSISTENT',
+    11: 'OFPBAC_UNSUPPORTED_ORDER',
+    12: 'OFPBAC_BAD_TAG',
+    13: 'OFPBAC_BAD_SET_TYPE',
+    14: 'OFPBAC_BAD_SET_LEN',
+    15: 'OFPBAC_BAD_SET_ARGUMENT',
+}
+
+# Identifiers from group ofp_bad_instruction_code
+OFPBIC_UNKNOWN_INST = 0
+OFPBIC_UNSUP_INST = 1
+OFPBIC_BAD_TABLE_ID = 2
+OFPBIC_UNSUP_METADATA = 3
+OFPBIC_UNSUP_METADATA_MASK = 4
+OFPBIC_BAD_EXPERIMENTER = 5
+OFPBIC_BAD_EXPERIMENTER_TYPE = 6
+OFPBIC_BAD_LEN = 7
+OFPBIC_EPERM = 8
+
+ofp_bad_instruction_code_map = {
+    0: 'OFPBIC_UNKNOWN_INST',
+    1: 'OFPBIC_UNSUP_INST',
+    2: 'OFPBIC_BAD_TABLE_ID',
+    3: 'OFPBIC_UNSUP_METADATA',
+    4: 'OFPBIC_UNSUP_METADATA_MASK',
+    5: 'OFPBIC_BAD_EXPERIMENTER',
+    6: 'OFPBIC_BAD_EXPERIMENTER_TYPE',
+    7: 'OFPBIC_BAD_LEN',
+    8: 'OFPBIC_EPERM',
+}
+
+# Identifiers from group ofp_bad_match_code
+OFPBMC_BAD_TYPE = 0
+OFPBMC_BAD_LEN = 1
+OFPBMC_BAD_TAG = 2
+OFPBMC_BAD_DL_ADDR_MASK = 3
+OFPBMC_BAD_NW_ADDR_MASK = 4
+OFPBMC_BAD_WILDCARDS = 5
+OFPBMC_BAD_FIELD = 6
+OFPBMC_BAD_VALUE = 7
+OFPBMC_BAD_MASK = 8
+OFPBMC_BAD_PREREQ = 9
+OFPBMC_DUP_FIELD = 10
+OFPBMC_EPERM = 11
+
+ofp_bad_match_code_map = {
+    0: 'OFPBMC_BAD_TYPE',
+    1: 'OFPBMC_BAD_LEN',
+    2: 'OFPBMC_BAD_TAG',
+    3: 'OFPBMC_BAD_DL_ADDR_MASK',
+    4: 'OFPBMC_BAD_NW_ADDR_MASK',
+    5: 'OFPBMC_BAD_WILDCARDS',
+    6: 'OFPBMC_BAD_FIELD',
+    7: 'OFPBMC_BAD_VALUE',
+    8: 'OFPBMC_BAD_MASK',
+    9: 'OFPBMC_BAD_PREREQ',
+    10: 'OFPBMC_DUP_FIELD',
+    11: 'OFPBMC_EPERM',
+}
+
+# Identifiers from group ofp_bad_request_code
+OFPBRC_BAD_VERSION = 0
+OFPBRC_BAD_TYPE = 1
+OFPBRC_BAD_STAT = 2
+OFPBRC_BAD_EXPERIMENTER = 3
+OFPBRC_BAD_EXPERIMENTER_TYPE = 4
+OFPBRC_EPERM = 5
+OFPBRC_BAD_LEN = 6
+OFPBRC_BUFFER_EMPTY = 7
+OFPBRC_BUFFER_UNKNOWN = 8
+OFPBRC_BAD_TABLE_ID = 9
+OFPBRC_IS_SLAVE = 10
+OFPBRC_BAD_PORT = 11
+OFPBRC_BAD_PACKET = 12
+
+ofp_bad_request_code_map = {
+    0: 'OFPBRC_BAD_VERSION',
+    1: 'OFPBRC_BAD_TYPE',
+    2: 'OFPBRC_BAD_STAT',
+    3: 'OFPBRC_BAD_EXPERIMENTER',
+    4: 'OFPBRC_BAD_EXPERIMENTER_TYPE',
+    5: 'OFPBRC_EPERM',
+    6: 'OFPBRC_BAD_LEN',
+    7: 'OFPBRC_BUFFER_EMPTY',
+    8: 'OFPBRC_BUFFER_UNKNOWN',
+    9: 'OFPBRC_BAD_TABLE_ID',
+    10: 'OFPBRC_IS_SLAVE',
+    11: 'OFPBRC_BAD_PORT',
+    12: 'OFPBRC_BAD_PACKET',
+}
+
+# Identifiers from group ofp_bsn_tcp_flag
+OFP_BSN_TCP_FLAG_FIN = 1
+OFP_BSN_TCP_FLAG_SYN = 2
+OFP_BSN_TCP_FLAG_RST = 4
+OFP_BSN_TCP_FLAG_PSH = 8
+OFP_BSN_TCP_FLAG_ACK = 16
+OFP_BSN_TCP_FLAG_URG = 32
+OFP_BSN_TCP_FLAG_ECE = 64
+OFP_BSN_TCP_FLAG_CWR = 128
+OFP_BSN_TCP_FLAG_NS = 256
+
+ofp_bsn_tcp_flag_map = {
+    1: 'OFP_BSN_TCP_FLAG_FIN',
+    2: 'OFP_BSN_TCP_FLAG_SYN',
+    4: 'OFP_BSN_TCP_FLAG_RST',
+    8: 'OFP_BSN_TCP_FLAG_PSH',
+    16: 'OFP_BSN_TCP_FLAG_ACK',
+    32: 'OFP_BSN_TCP_FLAG_URG',
+    64: 'OFP_BSN_TCP_FLAG_ECE',
+    128: 'OFP_BSN_TCP_FLAG_CWR',
+    256: 'OFP_BSN_TCP_FLAG_NS',
+}
+
+# Identifiers from group ofp_bsn_vport_l2gre_flags
+OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID = 1
+OF_BSN_VPORT_L2GRE_DSCP_ASSIGN = 2
+OF_BSN_VPORT_L2GRE_DSCP_COPY = 4
+OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID = 8
+OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID = 16
+
+ofp_bsn_vport_l2gre_flags_map = {
+    1: 'OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID',
+    2: 'OF_BSN_VPORT_L2GRE_DSCP_ASSIGN',
+    4: 'OF_BSN_VPORT_L2GRE_DSCP_COPY',
+    8: 'OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID',
+    16: 'OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID',
+}
+
+# Identifiers from group ofp_bsn_vport_q_in_q_untagged
+OF_BSN_VPORT_Q_IN_Q_UNTAGGED = 65535
+
+ofp_bsn_vport_q_in_q_untagged_map = {
+    65535: 'OF_BSN_VPORT_Q_IN_Q_UNTAGGED',
+}
+
+# Identifiers from group ofp_bsn_vport_status
+OF_BSN_VPORT_STATUS_OK = 0
+OF_BSN_VPORT_STATUS_FAILED = 1
+
+ofp_bsn_vport_status_map = {
+    0: 'OF_BSN_VPORT_STATUS_OK',
+    1: 'OF_BSN_VPORT_STATUS_FAILED',
+}
+
+# Identifiers from group ofp_capabilities
+OFPC_FLOW_STATS = 1
+OFPC_TABLE_STATS = 2
+OFPC_PORT_STATS = 4
+OFPC_GROUP_STATS = 8
+OFPC_IP_REASM = 32
+OFPC_QUEUE_STATS = 64
+OFPC_PORT_BLOCKED = 256
+
+ofp_capabilities_map = {
+    1: 'OFPC_FLOW_STATS',
+    2: 'OFPC_TABLE_STATS',
+    4: 'OFPC_PORT_STATS',
+    8: 'OFPC_GROUP_STATS',
+    32: 'OFPC_IP_REASM',
+    64: 'OFPC_QUEUE_STATS',
+    256: 'OFPC_PORT_BLOCKED',
+}
+
+# Identifiers from group ofp_config_flags
+OFPC_FRAG_NORMAL = 0
+OFPC_FRAG_DROP = 1
+OFPC_FRAG_REASM = 2
+OFPC_FRAG_MASK = 3
+OFPC_INVALID_TTL_TO_CONTROLLER = 4
+
+ofp_config_flags_map = {
+    0: 'OFPC_FRAG_NORMAL',
+    1: 'OFPC_FRAG_DROP',
+    2: 'OFPC_FRAG_REASM',
+    3: 'OFPC_FRAG_MASK',
+    4: 'OFPC_INVALID_TTL_TO_CONTROLLER',
+}
+
+# Identifiers from group ofp_controller_max_len
+OFPCML_MAX = 65509
+OFPCML_NO_BUFFER = 65535
+
+ofp_controller_max_len_map = {
+    65509: 'OFPCML_MAX',
+    65535: 'OFPCML_NO_BUFFER',
+}
+
+# Identifiers from group ofp_controller_role
+OFPCR_ROLE_NOCHANGE = 0
+OFPCR_ROLE_EQUAL = 1
+OFPCR_ROLE_MASTER = 2
+OFPCR_ROLE_SLAVE = 3
+
+ofp_controller_role_map = {
+    0: 'OFPCR_ROLE_NOCHANGE',
+    1: 'OFPCR_ROLE_EQUAL',
+    2: 'OFPCR_ROLE_MASTER',
+    3: 'OFPCR_ROLE_SLAVE',
+}
+
+# Identifiers from group ofp_error_type
+OFPET_HELLO_FAILED = 0
+OFPET_BAD_REQUEST = 1
+OFPET_BAD_ACTION = 2
+OFPET_BAD_INSTRUCTION = 3
+OFPET_BAD_MATCH = 4
+OFPET_FLOW_MOD_FAILED = 5
+OFPET_GROUP_MOD_FAILED = 6
+OFPET_PORT_MOD_FAILED = 7
+OFPET_TABLE_MOD_FAILED = 8
+OFPET_QUEUE_OP_FAILED = 9
+OFPET_SWITCH_CONFIG_FAILED = 10
+OFPET_ROLE_REQUEST_FAILED = 11
+OFPET_EXPERIMENTER = 65535
+
+ofp_error_type_map = {
+    0: 'OFPET_HELLO_FAILED',
+    1: 'OFPET_BAD_REQUEST',
+    2: 'OFPET_BAD_ACTION',
+    3: 'OFPET_BAD_INSTRUCTION',
+    4: 'OFPET_BAD_MATCH',
+    5: 'OFPET_FLOW_MOD_FAILED',
+    6: 'OFPET_GROUP_MOD_FAILED',
+    7: 'OFPET_PORT_MOD_FAILED',
+    8: 'OFPET_TABLE_MOD_FAILED',
+    9: 'OFPET_QUEUE_OP_FAILED',
+    10: 'OFPET_SWITCH_CONFIG_FAILED',
+    11: 'OFPET_ROLE_REQUEST_FAILED',
+    65535: 'OFPET_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_flow_mod_command
+OFPFC_ADD = 0
+OFPFC_MODIFY = 1
+OFPFC_MODIFY_STRICT = 2
+OFPFC_DELETE = 3
+OFPFC_DELETE_STRICT = 4
+
+ofp_flow_mod_command_map = {
+    0: 'OFPFC_ADD',
+    1: 'OFPFC_MODIFY',
+    2: 'OFPFC_MODIFY_STRICT',
+    3: 'OFPFC_DELETE',
+    4: 'OFPFC_DELETE_STRICT',
+}
+
+# Identifiers from group ofp_flow_mod_failed_code
+OFPFMFC_UNKNOWN = 0
+OFPFMFC_TABLE_FULL = 1
+OFPFMFC_BAD_TABLE_ID = 2
+OFPFMFC_OVERLAP = 3
+OFPFMFC_EPERM = 4
+OFPFMFC_BAD_TIMEOUT = 5
+OFPFMFC_BAD_COMMAND = 6
+OFPFMFC_BAD_FLAGS = 7
+
+ofp_flow_mod_failed_code_map = {
+    0: 'OFPFMFC_UNKNOWN',
+    1: 'OFPFMFC_TABLE_FULL',
+    2: 'OFPFMFC_BAD_TABLE_ID',
+    3: 'OFPFMFC_OVERLAP',
+    4: 'OFPFMFC_EPERM',
+    5: 'OFPFMFC_BAD_TIMEOUT',
+    6: 'OFPFMFC_BAD_COMMAND',
+    7: 'OFPFMFC_BAD_FLAGS',
+}
+
+# Identifiers from group ofp_flow_mod_flags
+OFPFF_SEND_FLOW_REM = 1
+OFPFF_CHECK_OVERLAP = 2
+OFPFF_RESET_COUNTS = 4
+
+ofp_flow_mod_flags_map = {
+    1: 'OFPFF_SEND_FLOW_REM',
+    2: 'OFPFF_CHECK_OVERLAP',
+    4: 'OFPFF_RESET_COUNTS',
+}
+
+# Identifiers from group ofp_flow_removed_reason
+OFPRR_IDLE_TIMEOUT = 0
+OFPRR_HARD_TIMEOUT = 1
+OFPRR_DELETE = 2
+OFPRR_GROUP_DELETE = 3
+
+ofp_flow_removed_reason_map = {
+    0: 'OFPRR_IDLE_TIMEOUT',
+    1: 'OFPRR_HARD_TIMEOUT',
+    2: 'OFPRR_DELETE',
+    3: 'OFPRR_GROUP_DELETE',
+}
+
+# Identifiers from group ofp_group
+OFPG_MAX = 4294967040
+OFPG_ALL = 4294967292
+OFPG_ANY = 4294967295
+
+ofp_group_map = {
+    4294967040: 'OFPG_MAX',
+    4294967292: 'OFPG_ALL',
+    4294967295: 'OFPG_ANY',
+}
+
+# Identifiers from group ofp_group_capabilities
+OFPGFC_SELECT_WEIGHT = 1
+OFPGFC_SELECT_LIVENESS = 2
+OFPGFC_CHAINING = 4
+OFPGFC_CHAINING_CHECKS = 8
+
+ofp_group_capabilities_map = {
+    1: 'OFPGFC_SELECT_WEIGHT',
+    2: 'OFPGFC_SELECT_LIVENESS',
+    4: 'OFPGFC_CHAINING',
+    8: 'OFPGFC_CHAINING_CHECKS',
+}
+
+# Identifiers from group ofp_group_mod_command
+OFPGC_ADD = 0
+OFPGC_MODIFY = 1
+OFPGC_DELETE = 2
+
+ofp_group_mod_command_map = {
+    0: 'OFPGC_ADD',
+    1: 'OFPGC_MODIFY',
+    2: 'OFPGC_DELETE',
+}
+
+# Identifiers from group ofp_group_mod_failed_code
+OFPGMFC_GROUP_EXISTS = 0
+OFPGMFC_INVALID_GROUP = 1
+OFPGMFC_WEIGHT_UNSUPPORTED = 2
+OFPGMFC_OUT_OF_GROUPS = 3
+OFPGMFC_OUT_OF_BUCKETS = 4
+OFPGMFC_CHAINING_UNSUPPORTED = 5
+OFPGMFC_WATCH_UNSUPPORTED = 6
+OFPGMFC_LOOP = 7
+OFPGMFC_UNKNOWN_GROUP = 8
+OFPGMFC_CHAINED_GROUP = 9
+OFPGMFC_BAD_TYPE = 10
+OFPGMFC_BAD_COMMAND = 11
+OFPGMFC_BAD_BUCKET = 12
+OFPGMFC_BAD_WATCH = 13
+OFPGMFC_EPERM = 14
+
+ofp_group_mod_failed_code_map = {
+    0: 'OFPGMFC_GROUP_EXISTS',
+    1: 'OFPGMFC_INVALID_GROUP',
+    2: 'OFPGMFC_WEIGHT_UNSUPPORTED',
+    3: 'OFPGMFC_OUT_OF_GROUPS',
+    4: 'OFPGMFC_OUT_OF_BUCKETS',
+    5: 'OFPGMFC_CHAINING_UNSUPPORTED',
+    6: 'OFPGMFC_WATCH_UNSUPPORTED',
+    7: 'OFPGMFC_LOOP',
+    8: 'OFPGMFC_UNKNOWN_GROUP',
+    9: 'OFPGMFC_CHAINED_GROUP',
+    10: 'OFPGMFC_BAD_TYPE',
+    11: 'OFPGMFC_BAD_COMMAND',
+    12: 'OFPGMFC_BAD_BUCKET',
+    13: 'OFPGMFC_BAD_WATCH',
+    14: 'OFPGMFC_EPERM',
+}
+
+# Identifiers from group ofp_group_type
+OFPGT_ALL = 0
+OFPGT_SELECT = 1
+OFPGT_INDIRECT = 2
+OFPGT_FF = 3
+
+ofp_group_type_map = {
+    0: 'OFPGT_ALL',
+    1: 'OFPGT_SELECT',
+    2: 'OFPGT_INDIRECT',
+    3: 'OFPGT_FF',
+}
+
+# Identifiers from group ofp_hello_failed_code
+OFPHFC_INCOMPATIBLE = 0
+OFPHFC_EPERM = 1
+
+ofp_hello_failed_code_map = {
+    0: 'OFPHFC_INCOMPATIBLE',
+    1: 'OFPHFC_EPERM',
+}
+
+# Identifiers from group ofp_instruction_type
+OFPIT_GOTO_TABLE = 1
+OFPIT_WRITE_METADATA = 2
+OFPIT_WRITE_ACTIONS = 3
+OFPIT_APPLY_ACTIONS = 4
+OFPIT_CLEAR_ACTIONS = 5
+OFPIT_EXPERIMENTER = 65535
+
+ofp_instruction_type_map = {
+    1: 'OFPIT_GOTO_TABLE',
+    2: 'OFPIT_WRITE_METADATA',
+    3: 'OFPIT_WRITE_ACTIONS',
+    4: 'OFPIT_APPLY_ACTIONS',
+    5: 'OFPIT_CLEAR_ACTIONS',
+    65535: 'OFPIT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_match_type
+OFPMT_STANDARD = 0
+OFPMT_OXM = 1
+
+ofp_match_type_map = {
+    0: 'OFPMT_STANDARD',
+    1: 'OFPMT_OXM',
+}
+
+# Identifiers from group ofp_oxm_class
+OFPXMC_NXM_0 = 0
+OFPXMC_NXM_1 = 1
+OFPXMC_OPENFLOW_BASIC = 32768
+OFPXMC_EXPERIMENTER = 65535
+
+ofp_oxm_class_map = {
+    0: 'OFPXMC_NXM_0',
+    1: 'OFPXMC_NXM_1',
+    32768: 'OFPXMC_OPENFLOW_BASIC',
+    65535: 'OFPXMC_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_packet_in_reason
+OFPR_NO_MATCH = 0
+OFPR_ACTION = 1
+OFPR_INVALID_TTL = 2
+
+ofp_packet_in_reason_map = {
+    0: 'OFPR_NO_MATCH',
+    1: 'OFPR_ACTION',
+    2: 'OFPR_INVALID_TTL',
+}
+
+# Identifiers from group ofp_port
+OFPP_MAX = 4294967040
+OFPP_IN_PORT = 4294967288
+OFPP_TABLE = 4294967289
+OFPP_NORMAL = 4294967290
+OFPP_FLOOD = 4294967291
+OFPP_ALL = 4294967292
+OFPP_CONTROLLER = 4294967293
+OFPP_LOCAL = 4294967294
+OFPP_ANY = 4294967295
+
+ofp_port_map = {
+    4294967040: 'OFPP_MAX',
+    4294967288: 'OFPP_IN_PORT',
+    4294967289: 'OFPP_TABLE',
+    4294967290: 'OFPP_NORMAL',
+    4294967291: 'OFPP_FLOOD',
+    4294967292: 'OFPP_ALL',
+    4294967293: 'OFPP_CONTROLLER',
+    4294967294: 'OFPP_LOCAL',
+    4294967295: 'OFPP_ANY',
+}
+
+# Identifiers from group ofp_port_config
+OFPPC_PORT_DOWN = 1
+OFPPC_NO_RECV = 4
+OFPPC_NO_FWD = 32
+OFPPC_NO_PACKET_IN = 64
+OFPPC_BSN_MIRROR_DEST = 2147483648
+
+ofp_port_config_map = {
+    1: 'OFPPC_PORT_DOWN',
+    4: 'OFPPC_NO_RECV',
+    32: 'OFPPC_NO_FWD',
+    64: 'OFPPC_NO_PACKET_IN',
+    2147483648: 'OFPPC_BSN_MIRROR_DEST',
+}
+
+# Identifiers from group ofp_port_features
+OFPPF_10MB_HD = 1
+OFPPF_10MB_FD = 2
+OFPPF_100MB_HD = 4
+OFPPF_100MB_FD = 8
+OFPPF_1GB_HD = 16
+OFPPF_1GB_FD = 32
+OFPPF_10GB_FD = 64
+OFPPF_40GB_FD = 128
+OFPPF_100GB_FD = 256
+OFPPF_1TB_FD = 512
+OFPPF_OTHER = 1024
+OFPPF_COPPER = 2048
+OFPPF_FIBER = 4096
+OFPPF_AUTONEG = 8192
+OFPPF_PAUSE = 16384
+OFPPF_PAUSE_ASYM = 32768
+
+ofp_port_features_map = {
+    1: 'OFPPF_10MB_HD',
+    2: 'OFPPF_10MB_FD',
+    4: 'OFPPF_100MB_HD',
+    8: 'OFPPF_100MB_FD',
+    16: 'OFPPF_1GB_HD',
+    32: 'OFPPF_1GB_FD',
+    64: 'OFPPF_10GB_FD',
+    128: 'OFPPF_40GB_FD',
+    256: 'OFPPF_100GB_FD',
+    512: 'OFPPF_1TB_FD',
+    1024: 'OFPPF_OTHER',
+    2048: 'OFPPF_COPPER',
+    4096: 'OFPPF_FIBER',
+    8192: 'OFPPF_AUTONEG',
+    16384: 'OFPPF_PAUSE',
+    32768: 'OFPPF_PAUSE_ASYM',
+}
+
+# Identifiers from group ofp_port_mod_failed_code
+OFPPMFC_BAD_PORT = 0
+OFPPMFC_BAD_HW_ADDR = 1
+OFPPMFC_BAD_CONFIG = 2
+OFPPMFC_BAD_ADVERTISE = 3
+OFPPMFC_EPERM = 4
+
+ofp_port_mod_failed_code_map = {
+    0: 'OFPPMFC_BAD_PORT',
+    1: 'OFPPMFC_BAD_HW_ADDR',
+    2: 'OFPPMFC_BAD_CONFIG',
+    3: 'OFPPMFC_BAD_ADVERTISE',
+    4: 'OFPPMFC_EPERM',
+}
+
+# Identifiers from group ofp_port_reason
+OFPPR_ADD = 0
+OFPPR_DELETE = 1
+OFPPR_MODIFY = 2
+
+ofp_port_reason_map = {
+    0: 'OFPPR_ADD',
+    1: 'OFPPR_DELETE',
+    2: 'OFPPR_MODIFY',
+}
+
+# Identifiers from group ofp_port_state
+OFPPS_LINK_DOWN = 1
+OFPPS_BLOCKED = 2
+OFPPS_LIVE = 4
+
+ofp_port_state_map = {
+    1: 'OFPPS_LINK_DOWN',
+    2: 'OFPPS_BLOCKED',
+    4: 'OFPPS_LIVE',
+}
+
+# Identifiers from group ofp_queue_op_failed_code
+OFPQOFC_BAD_PORT = 0
+OFPQOFC_BAD_QUEUE = 1
+OFPQOFC_EPERM = 2
+
+ofp_queue_op_failed_code_map = {
+    0: 'OFPQOFC_BAD_PORT',
+    1: 'OFPQOFC_BAD_QUEUE',
+    2: 'OFPQOFC_EPERM',
+}
+
+# Identifiers from group ofp_queue_properties
+OFPQT_MIN_RATE = 1
+OFPQT_MAX_RATE = 2
+OFPQT_EXPERIMENTER = 65535
+
+ofp_queue_properties_map = {
+    1: 'OFPQT_MIN_RATE',
+    2: 'OFPQT_MAX_RATE',
+    65535: 'OFPQT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_role_request_failed_code
+OFPRRFC_STALE = 0
+OFPRRFC_UNSUP = 1
+OFPRRFC_BAD_ROLE = 2
+
+ofp_role_request_failed_code_map = {
+    0: 'OFPRRFC_STALE',
+    1: 'OFPRRFC_UNSUP',
+    2: 'OFPRRFC_BAD_ROLE',
+}
+
+# Identifiers from group ofp_stats_reply_flags
+OFPSF_REPLY_MORE = 1
+
+ofp_stats_reply_flags_map = {
+    1: 'OFPSF_REPLY_MORE',
+}
+
+# Identifiers from group ofp_stats_request_flags
+
+ofp_stats_request_flags_map = {
+}
+
+# Identifiers from group ofp_stats_type
+OFPST_DESC = 0
+OFPST_FLOW = 1
+OFPST_AGGREGATE = 2
+OFPST_TABLE = 3
+OFPST_PORT = 4
+OFPST_QUEUE = 5
+OFPST_GROUP = 6
+OFPST_GROUP_DESC = 7
+OFPST_GROUP_FEATURES = 8
+OFPST_EXPERIMENTER = 65535
+
+ofp_stats_type_map = {
+    0: 'OFPST_DESC',
+    1: 'OFPST_FLOW',
+    2: 'OFPST_AGGREGATE',
+    3: 'OFPST_TABLE',
+    4: 'OFPST_PORT',
+    5: 'OFPST_QUEUE',
+    6: 'OFPST_GROUP',
+    7: 'OFPST_GROUP_DESC',
+    8: 'OFPST_GROUP_FEATURES',
+    65535: 'OFPST_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_switch_config_failed_code
+OFPSCFC_BAD_FLAGS = 0
+OFPSCFC_BAD_LEN = 1
+OFPSCFC_EPERM = 2
+
+ofp_switch_config_failed_code_map = {
+    0: 'OFPSCFC_BAD_FLAGS',
+    1: 'OFPSCFC_BAD_LEN',
+    2: 'OFPSCFC_EPERM',
+}
+
+# Identifiers from group ofp_table
+OFPTT_MAX = 254
+OFPTT_ALL = 255
+
+ofp_table_map = {
+    254: 'OFPTT_MAX',
+    255: 'OFPTT_ALL',
+}
+
+# Identifiers from group ofp_table_config
+OFPTC_TABLE_MISS_CONTROLLER = 0
+OFPTC_TABLE_MISS_CONTINUE = 1
+OFPTC_TABLE_MISS_DROP = 2
+OFPTC_TABLE_MISS_MASK = 3
+
+ofp_table_config_map = {
+    0: 'OFPTC_TABLE_MISS_CONTROLLER',
+    1: 'OFPTC_TABLE_MISS_CONTINUE',
+    2: 'OFPTC_TABLE_MISS_DROP',
+    3: 'OFPTC_TABLE_MISS_MASK',
+}
+
+# Identifiers from group ofp_table_mod_failed_code
+OFPTMFC_BAD_TABLE = 0
+OFPTMFC_BAD_CONFIG = 1
+OFPTMFC_EPERM = 2
+
+ofp_table_mod_failed_code_map = {
+    0: 'OFPTMFC_BAD_TABLE',
+    1: 'OFPTMFC_BAD_CONFIG',
+    2: 'OFPTMFC_EPERM',
+}
+
+# Identifiers from group ofp_type
+OFPT_HELLO = 0
+OFPT_ERROR = 1
+OFPT_ECHO_REQUEST = 2
+OFPT_ECHO_REPLY = 3
+OFPT_EXPERIMENTER = 4
+OFPT_FEATURES_REQUEST = 5
+OFPT_FEATURES_REPLY = 6
+OFPT_GET_CONFIG_REQUEST = 7
+OFPT_GET_CONFIG_REPLY = 8
+OFPT_SET_CONFIG = 9
+OFPT_PACKET_IN = 10
+OFPT_FLOW_REMOVED = 11
+OFPT_PORT_STATUS = 12
+OFPT_PACKET_OUT = 13
+OFPT_FLOW_MOD = 14
+OFPT_GROUP_MOD = 15
+OFPT_PORT_MOD = 16
+OFPT_TABLE_MOD = 17
+OFPT_STATS_REQUEST = 18
+OFPT_STATS_REPLY = 19
+OFPT_BARRIER_REQUEST = 20
+OFPT_BARRIER_REPLY = 21
+OFPT_QUEUE_GET_CONFIG_REQUEST = 22
+OFPT_QUEUE_GET_CONFIG_REPLY = 23
+OFPT_ROLE_REQUEST = 24
+OFPT_ROLE_REPLY = 25
+
+ofp_type_map = {
+    0: 'OFPT_HELLO',
+    1: 'OFPT_ERROR',
+    2: 'OFPT_ECHO_REQUEST',
+    3: 'OFPT_ECHO_REPLY',
+    4: 'OFPT_EXPERIMENTER',
+    5: 'OFPT_FEATURES_REQUEST',
+    6: 'OFPT_FEATURES_REPLY',
+    7: 'OFPT_GET_CONFIG_REQUEST',
+    8: 'OFPT_GET_CONFIG_REPLY',
+    9: 'OFPT_SET_CONFIG',
+    10: 'OFPT_PACKET_IN',
+    11: 'OFPT_FLOW_REMOVED',
+    12: 'OFPT_PORT_STATUS',
+    13: 'OFPT_PACKET_OUT',
+    14: 'OFPT_FLOW_MOD',
+    15: 'OFPT_GROUP_MOD',
+    16: 'OFPT_PORT_MOD',
+    17: 'OFPT_TABLE_MOD',
+    18: 'OFPT_STATS_REQUEST',
+    19: 'OFPT_STATS_REPLY',
+    20: 'OFPT_BARRIER_REQUEST',
+    21: 'OFPT_BARRIER_REPLY',
+    22: 'OFPT_QUEUE_GET_CONFIG_REQUEST',
+    23: 'OFPT_QUEUE_GET_CONFIG_REPLY',
+    24: 'OFPT_ROLE_REQUEST',
+    25: 'OFPT_ROLE_REPLY',
+}
+
+# Identifiers from group ofp_vlan_id
+OFPVID_NONE = 0
+OFPVID_PRESENT = 4096
+
+ofp_vlan_id_map = {
+    0: 'OFPVID_NONE',
+    4096: 'OFPVID_PRESENT',
+}
+
diff --git a/Fabric/Utilities/src/python/loxi/of12/instruction.py b/Fabric/Utilities/src/python/loxi/of12/instruction.py
new file mode 100644
index 0000000..4999e3e
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/instruction.py
@@ -0,0 +1,389 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of12']
+
+class instruction(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = instruction.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = instruction()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("instruction {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class apply_actions(instruction):
+    type = 4
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[4] = apply_actions
+
+class clear_actions(instruction):
+    type = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = clear_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("clear_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[5] = clear_actions
+
+class experimenter(instruction):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[65535] = experimenter
+
+class goto_table(instruction):
+    type = 1
+
+    def __init__(self, table_id=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = goto_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("goto_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[1] = goto_table
+
+class write_actions(instruction):
+    type = 3
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[3] = write_actions
+
+class write_metadata(instruction):
+    type = 2
+
+    def __init__(self, metadata=None, metadata_mask=None):
+        if metadata != None:
+            self.metadata = metadata
+        else:
+            self.metadata = 0
+        if metadata_mask != None:
+            self.metadata_mask = metadata_mask
+        else:
+            self.metadata_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.metadata))
+        packed.append(struct.pack("!Q", self.metadata_mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_metadata()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.metadata = reader.read("!Q")[0]
+        obj.metadata_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.metadata != other.metadata: return False
+        if self.metadata_mask != other.metadata_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("metadata = ");
+                q.text("%#x" % self.metadata)
+                q.text(","); q.breakable()
+                q.text("metadata_mask = ");
+                q.text("%#x" % self.metadata_mask)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[2] = write_metadata
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of12/message.py b/Fabric/Utilities/src/python/loxi/of12/message.py
new file mode 100644
index 0000000..c4f0ecb
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/message.py
@@ -0,0 +1,8443 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of12']
+
+class message(loxi.OFObject):
+    subtypes = {}
+
+    version = 3
+
+    def __init__(self, type=None, xid=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 1)
+        subclass = message.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = message()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        obj.type = reader.read("!B")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("message {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+
+class stats_reply(message):
+    subtypes = {}
+
+    version = 3
+    type = 19
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[19] = stats_reply
+
+class aggregate_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, packet_count=None, byte_count=None, flow_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if flow_count != None:
+            self.flow_count = flow_count
+        else:
+            self.flow_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(struct.pack("!L", self.flow_count))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.flow_count = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.flow_count != other.flow_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("flow_count = ");
+                q.text("%#x" % self.flow_count)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[2] = aggregate_stats_reply
+
+class stats_request(message):
+    subtypes = {}
+
+    version = 3
+    type = 18
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[18] = stats_request
+
+class aggregate_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[2] = aggregate_stats_request
+
+class error_msg(message):
+    subtypes = {}
+
+    version = 3
+    type = 1
+
+    def __init__(self, xid=None, err_type=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if err_type != None:
+            self.err_type = err_type
+        else:
+            self.err_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = error_msg.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.err_type = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.err_type != other.err_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[1] = error_msg
+
+class bad_action_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 2
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_action_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 2)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_action_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[2] = bad_action_error_msg
+
+class bad_instruction_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 3
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_instruction_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 3)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_instruction_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[3] = bad_instruction_error_msg
+
+class bad_match_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 4
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_match_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 4)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_match_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[4] = bad_match_error_msg
+
+class bad_request_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 1
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_request_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 1)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_request_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[1] = bad_request_error_msg
+
+class barrier_reply(message):
+    version = 3
+    type = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 21)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[21] = barrier_reply
+
+class barrier_request(message):
+    version = 3
+    type = 20
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 20)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[20] = barrier_request
+
+class experimenter(message):
+    subtypes = {}
+
+    version = 3
+    type = 4
+
+    def __init__(self, xid=None, experimenter=None, subtype=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[4] = experimenter
+
+class bsn_header(experimenter):
+    subtypes = {}
+
+    version = 3
+    type = 4
+    experimenter = 6035143
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = bsn_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn_header
+
+class bsn_bw_clear_data_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 22
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 22)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[22] = bsn_bw_clear_data_reply
+
+class bsn_bw_clear_data_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 21)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[21] = bsn_bw_clear_data_request
+
+class bsn_bw_enable_get_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 20
+
+    def __init__(self, xid=None, enabled=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enabled))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 20)
+        obj.enabled = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[20] = bsn_bw_enable_get_reply
+
+class bsn_bw_enable_get_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 19
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 19)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[19] = bsn_bw_enable_get_request
+
+class bsn_bw_enable_set_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 23
+
+    def __init__(self, xid=None, enable=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 23)
+        obj.enable = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[23] = bsn_bw_enable_set_reply
+
+class bsn_bw_enable_set_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 18
+
+    def __init__(self, xid=None, enable=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 18)
+        obj.enable = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[18] = bsn_bw_enable_set_request
+
+class bsn_get_interfaces_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, interfaces=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if interfaces != None:
+            self.interfaces = interfaces
+        else:
+            self.interfaces = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.interfaces))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.interfaces = loxi.generic_util.unpack_list(reader, ofp.common.bsn_interface.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.interfaces != other.interfaces: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("interfaces = ");
+                q.pp(self.interfaces)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[10] = bsn_get_interfaces_reply
+
+class bsn_get_interfaces_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[9] = bsn_get_interfaces_request
+
+class bsn_get_mirroring_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[5] = bsn_get_mirroring_reply
+
+class bsn_get_mirroring_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[4] = bsn_get_mirroring_request
+
+class bsn_pdu_rx_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 34
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 34)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[34] = bsn_pdu_rx_reply
+
+class bsn_pdu_rx_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 33
+
+    def __init__(self, xid=None, timeout_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if timeout_ms != None:
+            self.timeout_ms = timeout_ms
+        else:
+            self.timeout_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.timeout_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 33)
+        obj.timeout_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.timeout_ms != other.timeout_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("timeout_ms = ");
+                q.text("%#x" % self.timeout_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[33] = bsn_pdu_rx_request
+
+class bsn_pdu_rx_timeout(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 35
+
+    def __init__(self, xid=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_timeout()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 35)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[35] = bsn_pdu_rx_timeout
+
+class bsn_pdu_tx_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 32
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 32)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[32] = bsn_pdu_tx_reply
+
+class bsn_pdu_tx_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 31
+
+    def __init__(self, xid=None, tx_interval_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if tx_interval_ms != None:
+            self.tx_interval_ms = tx_interval_ms
+        else:
+            self.tx_interval_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.tx_interval_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 31)
+        obj.tx_interval_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.tx_interval_ms != other.tx_interval_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("tx_interval_ms = ");
+                q.text("%#x" % self.tx_interval_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[31] = bsn_pdu_tx_request
+
+class bsn_set_mirroring(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_mirroring()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_mirroring {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[3] = bsn_set_mirroring
+
+class bsn_set_pktin_suppression_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 25
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 25)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[25] = bsn_set_pktin_suppression_reply
+
+class bsn_set_pktin_suppression_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, enabled=None, idle_timeout=None, hard_timeout=None, priority=None, cookie=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.enabled))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!Q", self.cookie))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.enabled = reader.read("!B")[0]
+        reader.skip(1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.cookie = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.cookie != other.cookie: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[11] = bsn_set_pktin_suppression_request
+
+class experimenter_stats_reply(stats_reply):
+    subtypes = {}
+
+    version = 3
+    type = 19
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, subtype=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[65535] = experimenter_stats_reply
+
+class bsn_stats_reply(experimenter_stats_reply):
+    subtypes = {}
+
+    version = 3
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_reply.subtypes[6035143] = bsn_stats_reply
+
+class experimenter_stats_request(stats_request):
+    subtypes = {}
+
+    version = 3
+    type = 18
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, subtype=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[65535] = experimenter_stats_request
+
+class bsn_stats_request(experimenter_stats_request):
+    subtypes = {}
+
+    version = 3
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_request.subtypes[6035143] = bsn_stats_request
+
+class bsn_virtual_port_create_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, status=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.status = reader.read("!L")[0]
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[16] = bsn_virtual_port_create_reply
+
+class bsn_virtual_port_create_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, vport=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport != None:
+            self.vport = vport
+        else:
+            self.vport = ofp.bsn_vport()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.vport.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.vport = ofp.bsn_vport.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport != other.vport: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport = ");
+                q.pp(self.vport)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[15] = bsn_virtual_port_create_request
+
+class bsn_virtual_port_remove_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 26
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 26)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[26] = bsn_virtual_port_remove_reply
+
+class bsn_virtual_port_remove_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 17
+
+    def __init__(self, xid=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 17)
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[17] = bsn_virtual_port_remove_request
+
+class desc_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None, mfr_desc=None, hw_desc=None, sw_desc=None, serial_num=None, dp_desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if mfr_desc != None:
+            self.mfr_desc = mfr_desc
+        else:
+            self.mfr_desc = ""
+        if hw_desc != None:
+            self.hw_desc = hw_desc
+        else:
+            self.hw_desc = ""
+        if sw_desc != None:
+            self.sw_desc = sw_desc
+        else:
+            self.sw_desc = ""
+        if serial_num != None:
+            self.serial_num = serial_num
+        else:
+            self.serial_num = ""
+        if dp_desc != None:
+            self.dp_desc = dp_desc
+        else:
+            self.dp_desc = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!256s", self.mfr_desc))
+        packed.append(struct.pack("!256s", self.hw_desc))
+        packed.append(struct.pack("!256s", self.sw_desc))
+        packed.append(struct.pack("!32s", self.serial_num))
+        packed.append(struct.pack("!256s", self.dp_desc))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.mfr_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.hw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.sw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.serial_num = reader.read("!32s")[0].rstrip("\x00")
+        obj.dp_desc = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.mfr_desc != other.mfr_desc: return False
+        if self.hw_desc != other.hw_desc: return False
+        if self.sw_desc != other.sw_desc: return False
+        if self.serial_num != other.serial_num: return False
+        if self.dp_desc != other.dp_desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("mfr_desc = ");
+                q.pp(self.mfr_desc)
+                q.text(","); q.breakable()
+                q.text("hw_desc = ");
+                q.pp(self.hw_desc)
+                q.text(","); q.breakable()
+                q.text("sw_desc = ");
+                q.pp(self.sw_desc)
+                q.text(","); q.breakable()
+                q.text("serial_num = ");
+                q.pp(self.serial_num)
+                q.text(","); q.breakable()
+                q.text("dp_desc = ");
+                q.pp(self.dp_desc)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[0] = desc_stats_reply
+
+class desc_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[0] = desc_stats_request
+
+class echo_reply(message):
+    version = 3
+    type = 3
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[3] = echo_reply
+
+class echo_request(message):
+    version = 3
+    type = 2
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[2] = echo_request
+
+class experimenter_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 65535
+
+    def __init__(self, xid=None, subtype=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = experimenter_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 65535)
+        obj.subtype = reader.read("!H")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("experimenter = ");
+                q.text("%#x" % self.experimenter)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[65535] = experimenter_error_msg
+
+class features_reply(message):
+    version = 3
+    type = 6
+
+    def __init__(self, xid=None, datapath_id=None, n_buffers=None, n_tables=None, capabilities=None, reserved=None, ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if datapath_id != None:
+            self.datapath_id = datapath_id
+        else:
+            self.datapath_id = 0
+        if n_buffers != None:
+            self.n_buffers = n_buffers
+        else:
+            self.n_buffers = 0
+        if n_tables != None:
+            self.n_tables = n_tables
+        else:
+            self.n_tables = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if reserved != None:
+            self.reserved = reserved
+        else:
+            self.reserved = 0
+        if ports != None:
+            self.ports = ports
+        else:
+            self.ports = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.datapath_id))
+        packed.append(struct.pack("!L", self.n_buffers))
+        packed.append(struct.pack("!B", self.n_tables))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.reserved))
+        packed.append(loxi.generic_util.pack_list(self.ports))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.datapath_id = reader.read("!Q")[0]
+        obj.n_buffers = reader.read("!L")[0]
+        obj.n_tables = reader.read("!B")[0]
+        reader.skip(3)
+        obj.capabilities = reader.read("!L")[0]
+        obj.reserved = reader.read("!L")[0]
+        obj.ports = loxi.generic_util.unpack_list(reader, ofp.common.port_desc.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.datapath_id != other.datapath_id: return False
+        if self.n_buffers != other.n_buffers: return False
+        if self.n_tables != other.n_tables: return False
+        if self.capabilities != other.capabilities: return False
+        if self.reserved != other.reserved: return False
+        if self.ports != other.ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("datapath_id = ");
+                q.text("%#x" % self.datapath_id)
+                q.text(","); q.breakable()
+                q.text("n_buffers = ");
+                q.text("%#x" % self.n_buffers)
+                q.text(","); q.breakable()
+                q.text("n_tables = ");
+                q.text("%#x" % self.n_tables)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("reserved = ");
+                q.text("%#x" % self.reserved)
+                q.text(","); q.breakable()
+                q.text("ports = ");
+                q.pp(self.ports)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[6] = features_reply
+
+class features_request(message):
+    version = 3
+    type = 5
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[5] = features_request
+
+class flow_mod(message):
+    subtypes = {}
+
+    version = 3
+    type = 14
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, _command=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if _command != None:
+            self._command = _command
+        else:
+            self._command = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 25)
+        subclass = flow_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = flow_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj._command = util.unpack_fm_cmd(reader)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self._command != other._command: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[14] = flow_mod
+
+class flow_add(flow_mod):
+    version = 3
+    type = 14
+    _command = 0
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 0)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[0] = flow_add
+
+class flow_delete(flow_mod):
+    version = 3
+    type = 14
+    _command = 3
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 3)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[3] = flow_delete
+
+class flow_delete_strict(flow_mod):
+    version = 3
+    type = 14
+    _command = 4
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 4)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[4] = flow_delete_strict
+
+class flow_mod_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 5
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 5)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[5] = flow_mod_failed_error_msg
+
+class flow_modify(flow_mod):
+    version = 3
+    type = 14
+    _command = 1
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[1] = flow_modify
+
+class flow_modify_strict(flow_mod):
+    version = 3
+    type = 14
+    _command = 2
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 2)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[2] = flow_modify_strict
+
+class flow_removed(message):
+    version = 3
+    type = 11
+
+    def __init__(self, xid=None, cookie=None, priority=None, reason=None, table_id=None, duration_sec=None, duration_nsec=None, idle_timeout=None, hard_timeout=None, packet_count=None, byte_count=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_removed()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.priority != other.priority: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_removed {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[11] = flow_removed
+
+class flow_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.flow_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[1] = flow_stats_reply
+
+class flow_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[1] = flow_stats_request
+
+class get_config_reply(message):
+    version = 3
+    type = 8
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[8] = get_config_reply
+
+class get_config_request(message):
+    version = 3
+    type = 7
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[7] = get_config_request
+
+class group_mod(message):
+    subtypes = {}
+
+    version = 3
+    type = 15
+
+    def __init__(self, xid=None, command=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if command != None:
+            self.command = command
+        else:
+            self.command = 0
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = group_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = group_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.command = reader.read("!H")[0]
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.command != other.command: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[15] = group_mod
+
+class group_add(group_mod):
+    version = 3
+    type = 15
+    command = 0
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 0)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[0] = group_add
+
+class group_delete(group_mod):
+    version = 3
+    type = 15
+    command = 2
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[2] = group_delete
+
+class group_desc_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[7] = group_desc_stats_reply
+
+class group_desc_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[7] = group_desc_stats_request
+
+class group_features_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 8
+
+    def __init__(self, xid=None, flags=None, types=None, capabilities=None, max_groups_all=None, max_groups_select=None, max_groups_indirect=None, max_groups_ff=None, actions_all=None, actions_select=None, actions_indirect=None, actions_ff=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if types != None:
+            self.types = types
+        else:
+            self.types = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if max_groups_all != None:
+            self.max_groups_all = max_groups_all
+        else:
+            self.max_groups_all = 0
+        if max_groups_select != None:
+            self.max_groups_select = max_groups_select
+        else:
+            self.max_groups_select = 0
+        if max_groups_indirect != None:
+            self.max_groups_indirect = max_groups_indirect
+        else:
+            self.max_groups_indirect = 0
+        if max_groups_ff != None:
+            self.max_groups_ff = max_groups_ff
+        else:
+            self.max_groups_ff = 0
+        if actions_all != None:
+            self.actions_all = actions_all
+        else:
+            self.actions_all = 0
+        if actions_select != None:
+            self.actions_select = actions_select
+        else:
+            self.actions_select = 0
+        if actions_indirect != None:
+            self.actions_indirect = actions_indirect
+        else:
+            self.actions_indirect = 0
+        if actions_ff != None:
+            self.actions_ff = actions_ff
+        else:
+            self.actions_ff = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.types))
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.max_groups_all))
+        packed.append(struct.pack("!L", self.max_groups_select))
+        packed.append(struct.pack("!L", self.max_groups_indirect))
+        packed.append(struct.pack("!L", self.max_groups_ff))
+        packed.append(struct.pack("!L", self.actions_all))
+        packed.append(struct.pack("!L", self.actions_select))
+        packed.append(struct.pack("!L", self.actions_indirect))
+        packed.append(struct.pack("!L", self.actions_ff))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_features_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 8)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.types = reader.read("!L")[0]
+        obj.capabilities = reader.read("!L")[0]
+        obj.max_groups_all = reader.read("!L")[0]
+        obj.max_groups_select = reader.read("!L")[0]
+        obj.max_groups_indirect = reader.read("!L")[0]
+        obj.max_groups_ff = reader.read("!L")[0]
+        obj.actions_all = reader.read("!L")[0]
+        obj.actions_select = reader.read("!L")[0]
+        obj.actions_indirect = reader.read("!L")[0]
+        obj.actions_ff = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.types != other.types: return False
+        if self.capabilities != other.capabilities: return False
+        if self.max_groups_all != other.max_groups_all: return False
+        if self.max_groups_select != other.max_groups_select: return False
+        if self.max_groups_indirect != other.max_groups_indirect: return False
+        if self.max_groups_ff != other.max_groups_ff: return False
+        if self.actions_all != other.actions_all: return False
+        if self.actions_select != other.actions_select: return False
+        if self.actions_indirect != other.actions_indirect: return False
+        if self.actions_ff != other.actions_ff: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_features_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("types = ");
+                q.text("%#x" % self.types)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("max_groups_all = ");
+                q.text("%#x" % self.max_groups_all)
+                q.text(","); q.breakable()
+                q.text("max_groups_select = ");
+                q.text("%#x" % self.max_groups_select)
+                q.text(","); q.breakable()
+                q.text("max_groups_indirect = ");
+                q.text("%#x" % self.max_groups_indirect)
+                q.text(","); q.breakable()
+                q.text("max_groups_ff = ");
+                q.text("%#x" % self.max_groups_ff)
+                q.text(","); q.breakable()
+                q.text("actions_all = ");
+                q.text("%#x" % self.actions_all)
+                q.text(","); q.breakable()
+                q.text("actions_select = ");
+                q.text("%#x" % self.actions_select)
+                q.text(","); q.breakable()
+                q.text("actions_indirect = ");
+                q.text("%#x" % self.actions_indirect)
+                q.text(","); q.breakable()
+                q.text("actions_ff = ");
+                q.text("%#x" % self.actions_ff)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[8] = group_features_stats_reply
+
+class group_features_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 8
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_features_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 8)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_features_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[8] = group_features_stats_request
+
+class group_mod_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 6
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 6)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[6] = group_mod_failed_error_msg
+
+class group_modify(group_mod):
+    version = 3
+    type = 15
+    command = 1
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 1)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[1] = group_modify
+
+class group_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[6] = group_stats_reply
+
+class group_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, group_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.group_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[6] = group_stats_request
+
+class hello(message):
+    version = 3
+    type = 0
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[0] = hello
+
+class hello_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 0
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 0)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[0] = hello_failed_error_msg
+
+class nicira_header(experimenter):
+    subtypes = {}
+
+    version = 3
+    type = 4
+    experimenter = 8992
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = nicira_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira_header
+
+class packet_in(message):
+    version = 3
+    type = 10
+
+    def __init__(self, xid=None, buffer_id=None, total_len=None, reason=None, table_id=None, match=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if total_len != None:
+            self.total_len = total_len
+        else:
+            self.total_len = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(struct.pack("!H", self.total_len))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(self.match.pack())
+        packed.append('\x00' * 2)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_in()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.total_len = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.match = ofp.match.unpack(reader)
+        reader.skip(2)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.total_len != other.total_len: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.match != other.match: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("total_len = ");
+                q.text("%#x" % self.total_len)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[10] = packet_in
+
+class packet_out(message):
+    version = 3
+    type = 13
+
+    def __init__(self, xid=None, buffer_id=None, in_port=None, actions=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(struct.pack("!H", 0)) # placeholder for actions_len at index 6
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        packed[6] = struct.pack("!H", len(packed[-1]))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_out()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.in_port = util.unpack_port_no(reader)
+        _actions_len = reader.read("!H")[0]
+        reader.skip(6)
+        obj.actions = loxi.generic_util.unpack_list(reader.slice(_actions_len), ofp.action.action.unpack)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.in_port != other.in_port: return False
+        if self.actions != other.actions: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[13] = packet_out
+
+class port_mod(message):
+    version = 3
+    type = 16
+
+    def __init__(self, xid=None, port_no=None, hw_addr=None, config=None, mask=None, advertise=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        if advertise != None:
+            self.advertise = advertise
+        else:
+            self.advertise = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.mask))
+        packed.append(struct.pack("!L", self.advertise))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.config = reader.read("!L")[0]
+        obj.mask = reader.read("!L")[0]
+        obj.advertise = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.config != other.config: return False
+        if self.mask != other.mask: return False
+        if self.advertise != other.advertise: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+                q.text(","); q.breakable()
+                q.text("advertise = ");
+                q.text("%#x" % self.advertise)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[16] = port_mod
+
+class port_mod_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 7
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 7)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[7] = port_mod_failed_error_msg
+
+class port_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.port_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[4] = port_stats_reply
+
+class port_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[4] = port_stats_request
+
+class port_status(message):
+    version = 3
+    type = 12
+
+    def __init__(self, xid=None, reason=None, desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if desc != None:
+            self.desc = desc
+        else:
+            self.desc = ofp.port_desc()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 7)
+        packed.append(self.desc.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(7)
+        obj.desc = ofp.port_desc.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.reason != other.reason: return False
+        if self.desc != other.desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("desc = ");
+                q.pp(self.desc)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[12] = port_status
+
+class queue_get_config_reply(message):
+    version = 3
+    type = 23
+
+    def __init__(self, xid=None, port=None, queues=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if queues != None:
+            self.queues = queues
+        else:
+            self.queues = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.queues))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 23)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.queues = loxi.generic_util.unpack_list(reader, ofp.common.packet_queue.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        if self.queues != other.queues: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("queues = ");
+                q.pp(self.queues)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[23] = queue_get_config_reply
+
+class queue_get_config_request(message):
+    version = 3
+    type = 22
+
+    def __init__(self, xid=None, port=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 22)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+            q.breakable()
+        q.text('}')
+
+message.subtypes[22] = queue_get_config_request
+
+class queue_op_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 9
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_op_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 9)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_op_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[9] = queue_op_failed_error_msg
+
+class queue_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.queue_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[5] = queue_stats_reply
+
+class queue_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, port_no=None, queue_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[5] = queue_stats_request
+
+class role_reply(message):
+    version = 3
+    type = 25
+
+    def __init__(self, xid=None, role=None, generation_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 25)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        reader.skip(4)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[25] = role_reply
+
+class role_request(message):
+    version = 3
+    type = 24
+
+    def __init__(self, xid=None, role=None, generation_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 24)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        reader.skip(4)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[24] = role_request
+
+class role_request_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 11
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_request_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 11)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_request_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[11] = role_request_failed_error_msg
+
+class set_config(message):
+    version = 3
+    type = 9
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_config()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_config {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[9] = set_config
+
+class switch_config_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 10
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = switch_config_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 10)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("switch_config_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[10] = switch_config_failed_error_msg
+
+class table_mod(message):
+    version = 3
+    type = 17
+
+    def __init__(self, xid=None, table_id=None, config=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.config))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.config = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.config != other.config: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[17] = table_mod
+
+class table_mod_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 8
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 8)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[8] = table_mod_failed_error_msg
+
+class table_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[3] = table_stats_reply
+
+class table_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[3] = table_stats_request
+
+
+def parse_header(buf):
+    if len(buf) < 8:
+        raise loxi.ProtocolError("too short to be an OpenFlow message")
+    return struct.unpack_from("!BBHL", buf)
+
+def parse_message(buf):
+    msg_ver, msg_type, msg_len, msg_xid = parse_header(buf)
+    if msg_ver != ofp.OFP_VERSION and msg_type != ofp.OFPT_HELLO:
+        raise loxi.ProtocolError("wrong OpenFlow version (expected %d, got %d)" % (ofp.OFP_VERSION, msg_ver))
+    if len(buf) != msg_len:
+        raise loxi.ProtocolError("incorrect message size")
+    return message.unpack(loxi.generic_util.OFReader(buf))
diff --git a/Fabric/Utilities/src/python/loxi/of12/oxm.py b/Fabric/Utilities/src/python/loxi/of12/oxm.py
new file mode 100644
index 0000000..85accd4
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/oxm.py
@@ -0,0 +1,5502 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of12']
+
+class oxm(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type_len=None):
+        if type_len != None:
+            self.type_len = type_len
+        else:
+            self.type_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 0)
+        subclass = oxm.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = oxm()
+        obj.type_len = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type_len != other.type_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("oxm {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class arp_op(oxm):
+    type_len = 2147494402
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_op()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494402)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_op {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494402] = arp_op
+
+class arp_op_masked(oxm):
+    type_len = 2147494660
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_op_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494660)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_op_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494660] = arp_op_masked
+
+class arp_sha(oxm):
+    type_len = 2147495942
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_sha()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495942)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_sha {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495942] = arp_sha
+
+class arp_sha_masked(oxm):
+    type_len = 2147496204
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_sha_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496204)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_sha_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496204] = arp_sha_masked
+
+class arp_spa(oxm):
+    type_len = 2147494916
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_spa()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494916)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_spa {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494916] = arp_spa
+
+class arp_spa_masked(oxm):
+    type_len = 2147495176
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_spa_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495176)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_spa_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495176] = arp_spa_masked
+
+class arp_tha(oxm):
+    type_len = 2147496454
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tha()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496454)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tha {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496454] = arp_tha
+
+class arp_tha_masked(oxm):
+    type_len = 2147496716
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tha_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496716)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tha_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496716] = arp_tha_masked
+
+class arp_tpa(oxm):
+    type_len = 2147495428
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tpa()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495428)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tpa {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495428] = arp_tpa
+
+class arp_tpa_masked(oxm):
+    type_len = 2147495688
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tpa_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495688)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tpa_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495688] = arp_tpa_masked
+
+class bsn_egr_port_group_id(oxm):
+    type_len = 200196
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_egr_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200196)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_egr_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200196] = bsn_egr_port_group_id
+
+class bsn_egr_port_group_id_masked(oxm):
+    type_len = 200456
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_egr_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200456)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_egr_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200456] = bsn_egr_port_group_id_masked
+
+class bsn_global_vrf_allowed(oxm):
+    type_len = 198145
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_global_vrf_allowed()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198145)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_global_vrf_allowed {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198145] = bsn_global_vrf_allowed
+
+class bsn_global_vrf_allowed_masked(oxm):
+    type_len = 198402
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_global_vrf_allowed_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198402)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_global_vrf_allowed_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198402] = bsn_global_vrf_allowed_masked
+
+class bsn_in_ports_128(oxm):
+    type_len = 196624
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_128(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_128()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 196624)
+        obj.value = util.unpack_bitmap_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_128 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[196624] = bsn_in_ports_128
+
+class bsn_in_ports_128_masked(oxm):
+    type_len = 196896
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_128(self.value))
+        packed.append(util.pack_bitmap_128(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_128_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 196896)
+        obj.value = util.unpack_bitmap_128(reader)
+        obj.value_mask = util.unpack_bitmap_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_128_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[196896] = bsn_in_ports_128_masked
+
+class bsn_in_ports_512(oxm):
+    type_len = 206400
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_512(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_512()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206400)
+        obj.value = util.unpack_bitmap_512(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_512 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206400] = bsn_in_ports_512
+
+class bsn_in_ports_512_masked(oxm):
+    type_len = 206720
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_512(self.value))
+        packed.append(util.pack_bitmap_512(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_512_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206720)
+        obj.value = util.unpack_bitmap_512(reader)
+        obj.value_mask = util.unpack_bitmap_512(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_512_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206720] = bsn_in_ports_512_masked
+
+class bsn_ingress_port_group_id(oxm):
+    type_len = 206852
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_ingress_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206852)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_ingress_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206852] = bsn_ingress_port_group_id
+
+class bsn_ingress_port_group_id_masked(oxm):
+    type_len = 207112
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_ingress_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207112)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_ingress_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207112] = bsn_ingress_port_group_id_masked
+
+class bsn_l2_cache_hit(oxm):
+    type_len = 205825
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l2_cache_hit()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205825)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l2_cache_hit {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205825] = bsn_l2_cache_hit
+
+class bsn_l2_cache_hit_masked(oxm):
+    type_len = 206082
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l2_cache_hit_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206082)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l2_cache_hit_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206082] = bsn_l2_cache_hit_masked
+
+class bsn_l3_dst_class_id(oxm):
+    type_len = 199684
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_dst_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199684)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_dst_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199684] = bsn_l3_dst_class_id
+
+class bsn_l3_dst_class_id_masked(oxm):
+    type_len = 199944
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_dst_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199944)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_dst_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199944] = bsn_l3_dst_class_id_masked
+
+class bsn_l3_interface_class_id(oxm):
+    type_len = 198660
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_interface_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198660)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_interface_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198660] = bsn_l3_interface_class_id
+
+class bsn_l3_interface_class_id_masked(oxm):
+    type_len = 198920
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_interface_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198920)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_interface_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198920] = bsn_l3_interface_class_id_masked
+
+class bsn_l3_src_class_id(oxm):
+    type_len = 199172
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_src_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199172)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_src_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199172] = bsn_l3_src_class_id
+
+class bsn_l3_src_class_id_masked(oxm):
+    type_len = 199432
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_src_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199432)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_src_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199432] = bsn_l3_src_class_id_masked
+
+class bsn_lag_id(oxm):
+    type_len = 197124
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lag_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197124)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lag_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197124] = bsn_lag_id
+
+class bsn_lag_id_masked(oxm):
+    type_len = 197384
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lag_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197384)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lag_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197384] = bsn_lag_id_masked
+
+class bsn_tcp_flags(oxm):
+    type_len = 204802
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_tcp_flags()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204802)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tcp_flags {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204802] = bsn_tcp_flags
+
+class bsn_tcp_flags_masked(oxm):
+    type_len = 205060
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_tcp_flags_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205060)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tcp_flags_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205060] = bsn_tcp_flags_masked
+
+class bsn_udf0(oxm):
+    type_len = 200708
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf0()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200708)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf0 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200708] = bsn_udf0
+
+class bsn_udf0_masked(oxm):
+    type_len = 200968
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf0_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200968)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf0_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200968] = bsn_udf0_masked
+
+class bsn_udf1(oxm):
+    type_len = 201220
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf1()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201220)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf1 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201220] = bsn_udf1
+
+class bsn_udf1_masked(oxm):
+    type_len = 201480
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf1_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201480)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf1_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201480] = bsn_udf1_masked
+
+class bsn_udf2(oxm):
+    type_len = 201732
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf2()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201732)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf2 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201732] = bsn_udf2
+
+class bsn_udf2_masked(oxm):
+    type_len = 201992
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf2_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201992)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf2_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201992] = bsn_udf2_masked
+
+class bsn_udf3(oxm):
+    type_len = 202244
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf3()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202244)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202244] = bsn_udf3
+
+class bsn_udf3_masked(oxm):
+    type_len = 202504
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf3_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202504)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf3_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202504] = bsn_udf3_masked
+
+class bsn_udf4(oxm):
+    type_len = 202756
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf4()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202756)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf4 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202756] = bsn_udf4
+
+class bsn_udf4_masked(oxm):
+    type_len = 203016
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf4_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203016)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf4_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203016] = bsn_udf4_masked
+
+class bsn_udf5(oxm):
+    type_len = 203268
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf5()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203268)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf5 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203268] = bsn_udf5
+
+class bsn_udf5_masked(oxm):
+    type_len = 203528
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf5_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203528)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf5_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203528] = bsn_udf5_masked
+
+class bsn_udf6(oxm):
+    type_len = 203780
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf6()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203780)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf6 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203780] = bsn_udf6
+
+class bsn_udf6_masked(oxm):
+    type_len = 204040
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf6_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204040)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf6_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204040] = bsn_udf6_masked
+
+class bsn_udf7(oxm):
+    type_len = 204292
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf7()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204292)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf7 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204292] = bsn_udf7
+
+class bsn_udf7_masked(oxm):
+    type_len = 204552
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf7_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204552)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf7_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204552] = bsn_udf7_masked
+
+class bsn_vlan_xlate_port_group_id(oxm):
+    type_len = 205316
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_xlate_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205316)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_xlate_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205316] = bsn_vlan_xlate_port_group_id
+
+class bsn_vlan_xlate_port_group_id_masked(oxm):
+    type_len = 205576
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_xlate_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205576)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_xlate_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205576] = bsn_vlan_xlate_port_group_id_masked
+
+class bsn_vrf(oxm):
+    type_len = 197636
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197636)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197636] = bsn_vrf
+
+class bsn_vrf_masked(oxm):
+    type_len = 197896
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197896)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197896] = bsn_vrf_masked
+
+class eth_dst(oxm):
+    type_len = 2147485190
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485190)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485190] = eth_dst
+
+class eth_dst_masked(oxm):
+    type_len = 2147485452
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485452)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485452] = eth_dst_masked
+
+class eth_src(oxm):
+    type_len = 2147485702
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485702)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485702] = eth_src
+
+class eth_src_masked(oxm):
+    type_len = 2147485964
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485964)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485964] = eth_src_masked
+
+class eth_type(oxm):
+    type_len = 2147486210
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486210)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486210] = eth_type
+
+class eth_type_masked(oxm):
+    type_len = 2147486468
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486468)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486468] = eth_type_masked
+
+class icmpv4_code(oxm):
+    type_len = 2147493889
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_code()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493889)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493889] = icmpv4_code
+
+class icmpv4_code_masked(oxm):
+    type_len = 2147494146
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_code_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494146)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_code_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494146] = icmpv4_code_masked
+
+class icmpv4_type(oxm):
+    type_len = 2147493377
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493377)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493377] = icmpv4_type
+
+class icmpv4_type_masked(oxm):
+    type_len = 2147493634
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493634)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493634] = icmpv4_type_masked
+
+class icmpv6_code(oxm):
+    type_len = 2147499009
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_code()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499009)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499009] = icmpv6_code
+
+class icmpv6_code_masked(oxm):
+    type_len = 2147499266
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_code_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499266)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_code_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499266] = icmpv6_code_masked
+
+class icmpv6_type(oxm):
+    type_len = 2147498497
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498497)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498497] = icmpv6_type
+
+class icmpv6_type_masked(oxm):
+    type_len = 2147498754
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498754)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498754] = icmpv6_type_masked
+
+class in_phy_port(oxm):
+    type_len = 2147484164
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_phy_port()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484164)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_phy_port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484164] = in_phy_port
+
+class in_phy_port_masked(oxm):
+    type_len = 2147484424
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        packed.append(util.pack_port_no(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_phy_port_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484424)
+        obj.value = util.unpack_port_no(reader)
+        obj.value_mask = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_phy_port_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_port(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484424] = in_phy_port_masked
+
+class in_port(oxm):
+    type_len = 2147483652
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_port()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147483652)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147483652] = in_port
+
+class in_port_masked(oxm):
+    type_len = 2147483912
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        packed.append(util.pack_port_no(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_port_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147483912)
+        obj.value = util.unpack_port_no(reader)
+        obj.value_mask = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_port_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_port(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147483912] = in_port_masked
+
+class ip_dscp(oxm):
+    type_len = 2147487745
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_dscp()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487745)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_dscp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487745] = ip_dscp
+
+class ip_dscp_masked(oxm):
+    type_len = 2147488002
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_dscp_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488002)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_dscp_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488002] = ip_dscp_masked
+
+class ip_ecn(oxm):
+    type_len = 2147488257
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_ecn()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488257)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_ecn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488257] = ip_ecn
+
+class ip_ecn_masked(oxm):
+    type_len = 2147488514
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_ecn_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488514)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_ecn_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488514] = ip_ecn_masked
+
+class ip_proto(oxm):
+    type_len = 2147488769
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488769)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488769] = ip_proto
+
+class ip_proto_masked(oxm):
+    type_len = 2147489026
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489026)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489026] = ip_proto_masked
+
+class ipv4_dst(oxm):
+    type_len = 2147489796
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489796)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489796] = ipv4_dst
+
+class ipv4_dst_masked(oxm):
+    type_len = 2147490056
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490056)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490056] = ipv4_dst_masked
+
+class ipv4_src(oxm):
+    type_len = 2147489284
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489284)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489284] = ipv4_src
+
+class ipv4_src_masked(oxm):
+    type_len = 2147489544
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489544)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489544] = ipv4_src_masked
+
+class ipv6_dst(oxm):
+    type_len = 2147497488
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497488)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497488] = ipv6_dst
+
+class ipv6_dst_masked(oxm):
+    type_len = 2147497760
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497760)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497760] = ipv6_dst_masked
+
+class ipv6_flabel(oxm):
+    type_len = 2147497988
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_flabel()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497988)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_flabel {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497988] = ipv6_flabel
+
+class ipv6_flabel_masked(oxm):
+    type_len = 2147498248
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_flabel_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498248)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_flabel_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498248] = ipv6_flabel_masked
+
+class ipv6_nd_sll(oxm):
+    type_len = 2147500038
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_sll()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500038)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_sll {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500038] = ipv6_nd_sll
+
+class ipv6_nd_sll_masked(oxm):
+    type_len = 2147500300
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_sll_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500300)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_sll_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500300] = ipv6_nd_sll_masked
+
+class ipv6_nd_target(oxm):
+    type_len = 2147499536
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_target()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499536)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_target {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499536] = ipv6_nd_target
+
+class ipv6_nd_target_masked(oxm):
+    type_len = 2147499808
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_target_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499808)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_target_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499808] = ipv6_nd_target_masked
+
+class ipv6_nd_tll(oxm):
+    type_len = 2147500550
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_tll()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500550)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_tll {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500550] = ipv6_nd_tll
+
+class ipv6_nd_tll_masked(oxm):
+    type_len = 2147500812
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_tll_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500812)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_tll_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500812] = ipv6_nd_tll_masked
+
+class ipv6_src(oxm):
+    type_len = 2147496976
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496976)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496976] = ipv6_src
+
+class ipv6_src_masked(oxm):
+    type_len = 2147497248
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497248)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497248] = ipv6_src_masked
+
+class metadata(oxm):
+    type_len = 2147484680
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = metadata()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484680)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484680] = metadata
+
+class metadata_masked(oxm):
+    type_len = 2147484944
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        packed.append(struct.pack("!Q", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = metadata_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484944)
+        obj.value = reader.read("!Q")[0]
+        obj.value_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("metadata_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484944] = metadata_masked
+
+class mpls_label(oxm):
+    type_len = 2147501060
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501060)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501060] = mpls_label
+
+class mpls_label_masked(oxm):
+    type_len = 2147501320
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501320)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501320] = mpls_label_masked
+
+class mpls_tc(oxm):
+    type_len = 2147501569
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_tc()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501569)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_tc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501569] = mpls_tc
+
+class mpls_tc_masked(oxm):
+    type_len = 2147501826
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_tc_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501826)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_tc_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501826] = mpls_tc_masked
+
+class sctp_dst(oxm):
+    type_len = 2147492866
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492866)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492866] = sctp_dst
+
+class sctp_dst_masked(oxm):
+    type_len = 2147493124
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493124)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493124] = sctp_dst_masked
+
+class sctp_src(oxm):
+    type_len = 2147492354
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492354)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492354] = sctp_src
+
+class sctp_src_masked(oxm):
+    type_len = 2147492612
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492612)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492612] = sctp_src_masked
+
+class tcp_dst(oxm):
+    type_len = 2147490818
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490818)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490818] = tcp_dst
+
+class tcp_dst_masked(oxm):
+    type_len = 2147491076
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491076)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491076] = tcp_dst_masked
+
+class tcp_src(oxm):
+    type_len = 2147490306
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490306)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490306] = tcp_src
+
+class tcp_src_masked(oxm):
+    type_len = 2147490564
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490564)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490564] = tcp_src_masked
+
+class tunnel_ipv4_dst(oxm):
+    type_len = 81924
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81924)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81924] = tunnel_ipv4_dst
+
+class tunnel_ipv4_dst_masked(oxm):
+    type_len = 82184
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 82184)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[82184] = tunnel_ipv4_dst_masked
+
+class tunnel_ipv4_src(oxm):
+    type_len = 81412
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81412)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81412] = tunnel_ipv4_src
+
+class tunnel_ipv4_src_masked(oxm):
+    type_len = 81672
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81672)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81672] = tunnel_ipv4_src_masked
+
+class udp_dst(oxm):
+    type_len = 2147491842
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491842)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491842] = udp_dst
+
+class udp_dst_masked(oxm):
+    type_len = 2147492100
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492100)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492100] = udp_dst_masked
+
+class udp_src(oxm):
+    type_len = 2147491330
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491330)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491330] = udp_src
+
+class udp_src_masked(oxm):
+    type_len = 2147491588
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491588)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491588] = udp_src_masked
+
+class vlan_pcp(oxm):
+    type_len = 2147487233
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487233)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487233] = vlan_pcp
+
+class vlan_pcp_masked(oxm):
+    type_len = 2147487490
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487490)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487490] = vlan_pcp_masked
+
+class vlan_vid(oxm):
+    type_len = 2147486722
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486722)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486722] = vlan_vid
+
+class vlan_vid_masked(oxm):
+    type_len = 2147486980
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486980)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486980] = vlan_vid_masked
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of12/util.py b/Fabric/Utilities/src/python/loxi/of12/util.py
new file mode 100644
index 0000000..fd07b5f
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/util.py
@@ -0,0 +1,136 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+# Automatically generated by LOXI from template util.py
+# Do not modify
+
+import struct
+import loxi
+import const
+import common
+import action
+import instruction
+import oxm
+
+def pretty_mac(mac):
+    return ':'.join(["%02x" % x for x in mac])
+
+def pretty_ipv4(v):
+    return "%d.%d.%d.%d" % ((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF)
+
+def pretty_flags(v, flag_names):
+    set_flags = []
+    for flag_name in flag_names:
+        flag_value = getattr(const, flag_name)
+        if v & flag_value == flag_value:
+            set_flags.append(flag_name)
+        elif v & flag_value:
+            set_flags.append('%s&%#x' % (flag_name, v & flag_value))
+        v &= ~flag_value
+    if v:
+        set_flags.append("%#x" % v)
+    return '|'.join(set_flags) or '0'
+
+
+def pretty_port(v):
+    named_ports = [(k,v2) for (k,v2) in const.__dict__.iteritems() if k.startswith('OFPP_')]
+    for (k, v2) in named_ports:
+        if v == v2:
+            return k
+    return v
+
+def pack_port_no(value):
+    return struct.pack("!L", value)
+
+def unpack_port_no(reader):
+    return reader.read("!L")[0]
+
+def pack_fm_cmd(value):
+    return struct.pack("!B", value)
+
+def unpack_fm_cmd(reader):
+    return reader.read("!B")[0]
+
+def init_wc_bmap():
+    return 0
+
+def pack_wc_bmap(value):
+    return struct.pack("!Q", value)
+
+def unpack_wc_bmap(reader):
+    return reader.read("!Q")[0]
+
+def init_match_bmap():
+    return 0
+
+def pack_match_bmap(value):
+    return struct.pack("!Q", value)
+
+def unpack_match_bmap(reader):
+    return reader.read("!Q")[0]
+
+MASK64 = (1 << 64) - 1
+
+def pack_bitmap_128(value):
+    x = 0l
+    for y in value:
+        x |= 1 << y
+    return struct.pack("!QQ", (x >> 64) & MASK64, x & MASK64)
+
+def unpack_bitmap_128(reader):
+    hi, lo = reader.read("!QQ")
+    x = (hi << 64) | lo
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_bitmap_512(value):
+    words = [0] * 8
+    for v in value:
+        assert v < 512
+        words[7-v/64] |= 1 << (v % 64)
+    return struct.pack("!8Q", *words)
+
+def unpack_bitmap_512(reader):
+    words = reader.read("!8Q")
+    x = 0l
+    for word in words:
+        x <<= 64
+        x |= word
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_checksum_128(value):
+    return struct.pack("!QQ", (value >> 64) & MASK64, value & MASK64)
+
+def unpack_checksum_128(reader):
+    hi, lo = reader.read("!QQ")
+    return (hi << 64) | lo
diff --git a/Fabric/Utilities/src/python/loxi/of13/__init__.py b/Fabric/Utilities/src/python/loxi/of13/__init__.py
new file mode 100644
index 0000000..f4dc518
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/__init__.py
@@ -0,0 +1,37 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template init.py
+# Do not modify
+
+import const
+import bsn_tlv
+import meter_band
+import instruction
+import oxm
+import common
+import instruction_id
+import action
+import message
+import action_id
+from const import *
+from common import *
+from loxi import ProtocolError
diff --git a/Fabric/Utilities/src/python/loxi/of13/action.py b/Fabric/Utilities/src/python/loxi/of13/action.py
new file mode 100755
index 0000000..4875e74
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/action.py
@@ -0,0 +1,2205 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class action(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = action.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = action()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("action {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(action):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed.append(loxi.generic_util.pad_to(8, length))
+        length += len(packed[-1])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[65535] = experimenter
+"""
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_checksum(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_checksum_128(self.checksum))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_checksum()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_checksum {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_checksum
+
+class bsn_gentable(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, table_id=None, key=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.table_id))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.table_id = reader.read("!L")[0]
+        obj.key = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.key != other.key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_gentable
+
+class bsn_mirror(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, dest_port=None, vlan_tag=None, copy_stage=None):
+        if dest_port != None:
+            self.dest_port = dest_port
+        else:
+            self.dest_port = 0
+        if vlan_tag != None:
+            self.vlan_tag = vlan_tag
+        else:
+            self.vlan_tag = 0
+        if copy_stage != None:
+            self.copy_stage = copy_stage
+        else:
+            self.copy_stage = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dest_port))
+        packed.append(struct.pack("!L", self.vlan_tag))
+        packed.append(struct.pack("!B", self.copy_stage))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_mirror()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.dest_port = reader.read("!L")[0]
+        obj.vlan_tag = reader.read("!L")[0]
+        obj.copy_stage = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dest_port != other.dest_port: return False
+        if self.vlan_tag != other.vlan_tag: return False
+        if self.copy_stage != other.copy_stage: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_mirror {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dest_port = ");
+                q.text("%#x" % self.dest_port)
+                q.text(","); q.breakable()
+                q.text("vlan_tag = ");
+                q.text("%#x" % self.vlan_tag)
+                q.text(","); q.breakable()
+                q.text("copy_stage = ");
+                q.text("%#x" % self.copy_stage)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_mirror
+
+class bsn_set_tunnel_dst(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, dst=None):
+        if dst != None:
+            self.dst = dst
+        else:
+            self.dst = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dst))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_tunnel_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.dst = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dst != other.dst: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_tunnel_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dst = ");
+                q.text("%#x" % self.dst)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_set_tunnel_dst
+"""
+
+class copy_ttl_in(action):
+    type = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_in()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[12] = copy_ttl_in
+
+class copy_ttl_out(action):
+    type = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_out()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[11] = copy_ttl_out
+
+class dec_mpls_ttl(action):
+    type = 16
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[16] = dec_mpls_ttl
+
+class dec_nw_ttl(action):
+    type = 24
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[24] = dec_nw_ttl
+
+class group(action):
+    type = 22
+
+    def __init__(self, group_id=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.group_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.group_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[22] = group
+"""
+class nicira(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 8992
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = nicira.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!H")[0]
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira
+
+class nicira_dec_ttl(nicira):
+    type = 65535
+    experimenter = 8992
+    subtype = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_dec_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == 18)
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_dec_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+nicira.subtypes[18] = nicira_dec_ttl
+"""
+class output(action):
+    type = 0
+
+    def __init__(self, port=None, max_len=None):
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if max_len != None:
+            self.max_len = max_len
+        else:
+            self.max_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", self.max_len))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = output()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.port = util.unpack_port_no(reader)
+        obj.max_len = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port != other.port: return False
+        if self.max_len != other.max_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("max_len = ");
+                q.text("%#x" % self.max_len)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[0] = output
+
+class pop_mpls(action):
+    type = 20
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[20] = pop_mpls
+
+class pop_pbb(action):
+    type = 27
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 27)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[27] = pop_pbb
+
+class pop_vlan(action):
+    type = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[18] = pop_vlan
+
+class push_mpls(action):
+    type = 19
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[19] = push_mpls
+
+class push_pbb(action):
+    type = 26
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 26)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[26] = push_pbb
+
+class push_vlan(action):
+    type = 17
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[17] = push_vlan
+
+class set_field(action):
+    type = 25
+
+    def __init__(self, field=None):
+        if field != None:
+            self.field = field
+        else:
+            self.field = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(self.field.pack())
+        length = sum([len(x) for x in packed])
+        packed.append(loxi.generic_util.pad_to(8, length))
+        length += len(packed[-1])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_field()
+        _type = reader.read("!H")[0]
+        assert(_type == 25)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.field = ofp.oxm.oxm.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.field != other.field: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_field {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("field = ");
+                q.pp(self.field)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[25] = set_field
+
+class set_mpls_ttl(action):
+    type = 15
+
+    def __init__(self, mpls_ttl=None):
+        if mpls_ttl != None:
+            self.mpls_ttl = mpls_ttl
+        else:
+            self.mpls_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.mpls_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.mpls_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mpls_ttl != other.mpls_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mpls_ttl = ");
+                q.text("%#x" % self.mpls_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[15] = set_mpls_ttl
+
+class set_nw_ttl(action):
+    type = 23
+
+    def __init__(self, nw_ttl=None):
+        if nw_ttl != None:
+            self.nw_ttl = nw_ttl
+        else:
+            self.nw_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.nw_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_ttl != other.nw_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_ttl = ");
+                q.text("%#x" % self.nw_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[23] = set_nw_ttl
+
+class set_queue(action):
+    type = 21
+
+    def __init__(self, queue_id=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_queue()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[21] = set_queue
+
+OFDPA_EXPERIMETER =0x00001018
+
+class ofdpa(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        #8 is offset, ref OFReader
+        subtype, = reader.peek('!H', 8)
+        subclass = ofdpa.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = ofdpa()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        obj.subtype = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[OFDPA_EXPERIMETER] = ofdpa
+
+OFDPA_ACT_PUSH_L2_HEADER=1
+OFDPA_ACT_POP_L2_HEADER=2 
+OFDPA_ACT_PUSH_CW=3 
+OFDPA_ACT_POP_CW=4
+OFDPA_ACT_COPY_TC_IN=5
+OFDPA_ACT_COPY_TC_OUT=6
+OFDPA_ACT_SET_TC_FROM_TABLE=7
+OFDPA_ACT_SET_PCP_DFI_FROM_TABLE=9
+OFDPA_ACT_OAM_LM_RX_COUNT=10
+OFDPA_ACT_OAM_LM_TX_COUNT=11
+OFDPA_ACT_OAM_SET_COUNTER_FIELDS=12
+OFDPA_ACT_DEC_TTL_MTU=13
+OFDPA_ACT_CHECK_DROP_STATUS=14
+OFDPA_ACT_SET_QOS_FROM_TABLE=15
+
+
+class ofdpa_push_l2_header(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_PUSH_L2_HEADER
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_push_l2_header()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_PUSH_L2_HEADER)   
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_push_l2_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_push_l2_header");
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_PUSH_L2_HEADER] = ofdpa_push_l2_header
+
+class ofdpa_pop_l2_header(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_POP_L2_HEADER
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)        
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_pop_l2_header()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_POP_L2_HEADER)          
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_pop_l2_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_pop_l2_header");
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_POP_L2_HEADER] = ofdpa_pop_l2_header
+
+class ofdpa_push_cw(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_PUSH_CW
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)        
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_push_cw()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_PUSH_CW)          
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_push_cw {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_push_cw");
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_PUSH_CW] = ofdpa_push_cw
+
+class ofdpa_pop_cw(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_POP_CW
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)        
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_pop_cw()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_POP_CW)          
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_pop_cw {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_pop_cw");
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_POP_CW] = ofdpa_pop_cw
+
+class ofdpa_copy_tc_in(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_COPY_TC_IN
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)        
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_copy_tc_in()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_COPY_TC_IN)  
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_copy_tc_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_copy_tc_in");
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_COPY_TC_IN] = ofdpa_copy_tc_in
+
+class ofdpa_copy_tc_out(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_COPY_TC_OUT
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)        
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_copy_tc_out()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_COPY_TC_OUT)        
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_copy_tc_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_copy_tc_out");
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_COPY_TC_OUT] = ofdpa_copy_tc_out
+
+class ofdpa_dec_ttl_mtu(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_DEC_TTL_MTU
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)        
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_dec_ttl_mtu()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_DEC_TTL_MTU)        
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_dec_ttl_mtu {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_dec_ttl_mtu");
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_DEC_TTL_MTU] = ofdpa_dec_ttl_mtu
+
+class ofdpa_set_tc_from_table(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_SET_TC_FROM_TABLE
+
+    def __init__(self, qos_index=None):
+        if qos_index != None:
+            self.qos_index = qos_index
+        else:
+            self.qos_index = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!B", self.qos_index))
+        packed.append('\x00' * 5)        
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_set_tc_from_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_SET_TC_FROM_TABLE)
+        obj.qos_index = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.qos_index != other.qos_index: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_set_tc_from_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_set_tc_from_table");
+                q.pp(self.qos_index)
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_SET_TC_FROM_TABLE] = ofdpa_set_tc_from_table
+
+
+class ofdpa_set_pcp_dfi_from_table(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_SET_PCP_DFI_FROM_TABLE
+
+    def __init__(self, qos_index=None):
+        if qos_index != None:
+            self.qos_index = qos_index
+        else:
+            self.qos_index = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!B", self.qos_index))
+        packed.append('\x00' * 5)         
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_set_pcp_dfi_from_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_SET_PCP_DFI_FROM_TABLE)
+        obj.qos_index = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.qos_index != other.qos_index: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_set_pcp_dfi_from_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_set_pcp_dfi_from_table");
+                q.pp(self.qos_index)
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_SET_PCP_DFI_FROM_TABLE] = ofdpa_set_pcp_dfi_from_table
+
+
+class ofdpa_check_drop_status(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_CHECK_DROP_STATUS
+
+    def __init__(self, index, status_type):
+        self.index = index
+        self.status_type  = status_type
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!L", self.index))
+        packed.append(struct.pack("!B", self.status_type))  
+        packed.append('\x00' * 1)    
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_check_drop_status()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_CHECK_DROP_STATUS)
+        obj.status_type  = reader.read("!L")[0]
+        obj.index = reader.read("!B")[0]        
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.index != other.index: return False
+        if self.status_type != other.status_type: return False        
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_check_drop_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_check_drop_status = ");
+                q.pp(self.index)
+                q.pp(self.status_type)                
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_CHECK_DROP_STATUS] = ofdpa_check_drop_status
+
+
+class ofdpa_set_qos_from_table(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_SET_QOS_FROM_TABLE
+
+    def __init__(self, qos_index, mpls_tc):
+        self.qos_index = qos_index
+        self.mpls_tc  = mpls_tc
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!B", self.qos_index))
+        packed.append(struct.pack("!B", self.mpls_tc))   
+        packed.append('\x00' * 4)           
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_check_drop_status()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_SET_QOS_FROM_TABLE)
+        obj.qos_index = reader.read("!B")[0]
+        obj.mpls_tc  = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.qos_index != other.qos_index: return False
+        if self.mpls_tc != other.mpls_tc: return False        
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_set_qos_from_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_set_qos_from_table = ");
+                q.pp(self.qos_index)
+                q.pp(self.mpls_tc)                
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_SET_QOS_FROM_TABLE] = ofdpa_set_qos_from_table
+
+
+class ofdpa_oam_lm_tx_count(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_OAM_LM_TX_COUNT
+
+    def __init__(self, lmep_id, traffic_class):
+        self.lmep_id = lmep_id
+        self.traffic_class  = traffic_class
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!L", self.lmep_id))
+        packed.append(struct.pack("!B", self.traffic_class))   
+        packed.append('\x00' * 1)   
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_check_drop_status()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_OAM_LM_TX_COUNT)
+        obj.lmep_id = reader.read("!L")[0]
+        obj.traffic_class  = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.lmep_id != other.lmep_id: return False
+        if self.traffic_class != other.traffic_class: return False        
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_oam_lm_tx_count {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_oam_lm_tx_count = ");
+                q.pp(self.lmep_id)
+                q.pp(self.traffic_class)                
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_OAM_LM_TX_COUNT] = ofdpa_oam_lm_tx_count
+
+class ofdpa_oam_lm_rx_count(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_OAM_LM_RX_COUNT
+
+    def __init__(self, lmep_id, traffic_class):
+        self.lmep_id = lmep_id
+        self.traffic_class  = traffic_class
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!L", self.lmep_id))
+        packed.append(struct.pack("!B", self.traffic_class))  
+        packed.append('\x00' * 1)   
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_check_drop_status()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_OAM_LM_RX_COUNT)
+        obj.lmep_id = reader.read("!L")[0]
+        obj.traffic_class  = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.lmep_id != other.lmep_id: return False
+        if self.traffic_class != other.traffic_class: return False        
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_oam_lm_rx_count {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_oam_lm_rx_count = ");
+                q.pp(self.lmep_id)
+                q.pp(self.traffic_class)                
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_OAM_LM_RX_COUNT] = ofdpa_oam_lm_rx_count
+
+
+class ofdpa_oam_set_counter_field(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_OAM_SET_COUNTER_FIELDS
+
+    def __init__(self, lmep_id, traffic_class):
+        self.lmep_id = lmep_id
+        self.traffic_class  = traffic_class
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!L", self.lmep_id))
+        packed.append(struct.pack("!B", self.traffic_class))  
+        packed.append('\x00' * 1)   
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_check_drop_status()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_OAM_SET_COUNTER_FIELDS)
+        obj.lmep_id = reader.read("!L")[0]
+        obj.traffic_class  = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.lmep_id != other.lmep_id: return False
+        if self.traffic_class != other.traffic_class: return False        
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_oam_set_counter_field {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_oam_set_counter_field = ");
+                q.pp(self.lmep_id)
+                q.pp(self.traffic_class)                
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_OAM_SET_COUNTER_FIELDS] = ofdpa_oam_set_counter_field
+
+class copy_field(action):
+    type = 65535
+    experimenter = 0x4f4e4600  # ONF_EXPERIMENTER_ID
+    exp_type = 3200            # ONFTFP_ET_WRITE_COPYFIELD
+
+    def __init__(self, n_bits=None, src_offset=None, dst_offset=None, oxm_ids=None):
+        if n_bits != None:
+            self.n_bits = n_bits
+        else:
+            self.n_bits = 0
+        if src_offset != None:
+            self.src_offset = src_offset
+        else:
+            self.src_offset = 0
+        if dst_offset != None:
+            self.dst_offset = dst_offset
+        else:
+            self.dst_offset = 0
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = [ ]
+        return
+
+    def pack( self ):
+        packed = [ ]
+        packed.append( struct.pack( "!H", self.type ) )
+        packed.append( struct.pack( "!H", 0 ) )  # placeholder for len at index 1
+        packed.append( struct.pack( "!L", self.experimenter ) )
+        packed.append( struct.pack( "!H", self.exp_type ) )
+        packed.append( '\x00' * 2 )
+        packed.append( struct.pack( "!H", self.n_bits ) )
+        packed.append( struct.pack( "!H", self.src_offset ) )
+        packed.append( struct.pack( "!H", self.dst_offset ) )
+        packed.append( '\x00' * 2 )
+        packed.append( "".join(self.oxm_ids ) )
+        length = sum( [ len( x ) for x in packed ] )
+        packed[ 1 ] = struct.pack( "!H", length )
+        return ''.join( packed )
+
+    @staticmethod
+    def unpack( reader ):
+        obj = copy_field()
+        _type = reader.read( "!H" )[ 0 ]
+        _len = reader.read( "!H" )[ 0 ]
+        orig_reader = reader
+        reader = orig_reader.slice( _len, 4 )
+        obj.n_bits = reader.read( "!H" )[ 0 ]
+        obj.src_offset = reader.read( "!H" )[ 0 ]
+        obj.dst_offset = reader.read( "!H" )[ 0 ]
+        reader.skip( 2 )
+        obj.oxm_ids = loxi.generic_util.unpack_list( reader, ofp.oxm.oxm.unpack )
+        return obj
+
+    def __eq__( self, other ):
+        if type( self ) != type( other ): return False
+        if self.n_bits != other.n_bits: return False
+        if self.src_offset != other.src_offset: return False
+        if self.dst_offset != other.dst_offset: return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print( self, q ):
+        q.text( "copy_field {" )
+        with q.group():
+            with q.indent( 2 ):
+                q.breakable()
+                q.text( "n_bits = " )
+                q.text( "%#x" % self.n_bits )
+                q.text( "," )
+                q.breakable()
+                q.text( "src_offset = " )
+                q.text( "%#x" % self.src_offset )
+                q.text( "," )
+                q.breakable()
+                q.text( "dst_offset = " )
+                q.text( "%#x" % self.dst_offset )
+                q.text( "," )
+                q.breakable()
+                q.text( "oxm_ids = " )
+                q.pp( self.oxm_ids )
+            q.breakable()
+        q.text( '}' )
diff --git a/Fabric/Utilities/src/python/loxi/of13/action_id.py b/Fabric/Utilities/src/python/loxi/of13/action_id.py
new file mode 100644
index 0000000..5814e31
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/action_id.py
@@ -0,0 +1,1082 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class action_id(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = action_id.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = action_id()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("action_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(action_id):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_checksum(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_checksum()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_checksum {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_checksum
+
+class bsn_gentable(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_gentable
+
+class bsn_mirror(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_mirror()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_mirror {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_mirror
+
+class bsn_set_tunnel_dst(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_tunnel_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_tunnel_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_set_tunnel_dst
+
+class copy_ttl_in(action_id):
+    type = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_in()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[12] = copy_ttl_in
+
+class copy_ttl_out(action_id):
+    type = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_out()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[11] = copy_ttl_out
+
+class dec_mpls_ttl(action_id):
+    type = 16
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[16] = dec_mpls_ttl
+
+class dec_nw_ttl(action_id):
+    type = 24
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[24] = dec_nw_ttl
+
+class group(action_id):
+    type = 22
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[22] = group
+
+class nicira(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 8992
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = nicira.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira
+
+class nicira_dec_ttl(nicira):
+    type = 65535
+    experimenter = 8992
+    subtype = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_dec_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == 18)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_dec_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+nicira.subtypes[18] = nicira_dec_ttl
+
+class output(action_id):
+    type = 0
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = output()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[0] = output
+
+class pop_mpls(action_id):
+    type = 20
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[20] = pop_mpls
+
+class pop_pbb(action_id):
+    type = 27
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 27)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[27] = pop_pbb
+
+class pop_vlan(action_id):
+    type = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[18] = pop_vlan
+
+class push_mpls(action_id):
+    type = 19
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[19] = push_mpls
+
+class push_pbb(action_id):
+    type = 26
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 26)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[26] = push_pbb
+
+class push_vlan(action_id):
+    type = 17
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[17] = push_vlan
+
+class set_field(action_id):
+    type = 25
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_field()
+        _type = reader.read("!H")[0]
+        assert(_type == 25)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_field {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[25] = set_field
+
+class set_mpls_ttl(action_id):
+    type = 15
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[15] = set_mpls_ttl
+
+class set_nw_ttl(action_id):
+    type = 23
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[23] = set_nw_ttl
+
+class set_queue(action_id):
+    type = 21
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_queue()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[21] = set_queue
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of13/bsn_tlv.py b/Fabric/Utilities/src/python/loxi/of13/bsn_tlv.py
new file mode 100644
index 0000000..a9e4ff0
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/bsn_tlv.py
@@ -0,0 +1,3881 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class bsn_tlv(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bsn_tlv.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_tlv()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tlv {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class actor_key(bsn_tlv):
+    type = 44
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_key()
+        _type = reader.read("!H")[0]
+        assert(_type == 44)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_key {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[44] = actor_key
+
+class actor_port_num(bsn_tlv):
+    type = 43
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_port_num()
+        _type = reader.read("!H")[0]
+        assert(_type == 43)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_port_num {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[43] = actor_port_num
+
+class actor_port_priority(bsn_tlv):
+    type = 42
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_port_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 42)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_port_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[42] = actor_port_priority
+
+class actor_state(bsn_tlv):
+    type = 53
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_state()
+        _type = reader.read("!H")[0]
+        assert(_type == 53)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_state {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[53] = actor_state
+
+class actor_system_mac(bsn_tlv):
+    type = 41
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_system_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 41)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_system_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[41] = actor_system_mac
+
+class actor_system_priority(bsn_tlv):
+    type = 40
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_system_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 40)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_system_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[40] = actor_system_priority
+
+class anchor(bsn_tlv):
+    type = 81
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = anchor()
+        _type = reader.read("!H")[0]
+        assert(_type == 81)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("anchor {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[81] = anchor
+
+class broadcast_query_timeout(bsn_tlv):
+    type = 10
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = broadcast_query_timeout()
+        _type = reader.read("!H")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("broadcast_query_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[10] = broadcast_query_timeout
+
+class bucket(bsn_tlv):
+    type = 64
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket()
+        _type = reader.read("!H")[0]
+        assert(_type == 64)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[64] = bucket
+
+class circuit_id(bsn_tlv):
+    type = 14
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(self.value)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = circuit_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("circuit_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[14] = circuit_id
+
+class convergence_status(bsn_tlv):
+    type = 45
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = convergence_status()
+        _type = reader.read("!H")[0]
+        assert(_type == 45)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("convergence_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[45] = convergence_status
+
+class crc_enabled(bsn_tlv):
+    type = 22
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = crc_enabled()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("crc_enabled {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[22] = crc_enabled
+
+class data(bsn_tlv):
+    type = 55
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(self.value)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = data()
+        _type = reader.read("!H")[0]
+        assert(_type == 55)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("data {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[55] = data
+
+class eth_dst(bsn_tlv):
+    type = 33
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 33)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[33] = eth_dst
+
+class eth_src(bsn_tlv):
+    type = 32
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 32)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[32] = eth_src
+
+class external_gateway_ip(bsn_tlv):
+    type = 26
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_gateway_ip()
+        _type = reader.read("!H")[0]
+        assert(_type == 26)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_gateway_ip {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[26] = external_gateway_ip
+
+class external_gateway_mac(bsn_tlv):
+    type = 29
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_gateway_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 29)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_gateway_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[29] = external_gateway_mac
+
+class external_ip(bsn_tlv):
+    type = 23
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_ip()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_ip {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[23] = external_ip
+
+class external_mac(bsn_tlv):
+    type = 24
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[24] = external_mac
+
+class external_netmask(bsn_tlv):
+    type = 25
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_netmask()
+        _type = reader.read("!H")[0]
+        assert(_type == 25)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_netmask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[25] = external_netmask
+
+class generation_id(bsn_tlv):
+    type = 80
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = generation_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 80)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("generation_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[80] = generation_id
+
+class header_size(bsn_tlv):
+    type = 31
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = header_size()
+        _type = reader.read("!H")[0]
+        assert(_type == 31)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("header_size {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[31] = header_size
+
+class icmp_code(bsn_tlv):
+    type = 69
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmp_code()
+        _type = reader.read("!H")[0]
+        assert(_type == 69)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmp_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[69] = icmp_code
+
+class icmp_id(bsn_tlv):
+    type = 70
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmp_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 70)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmp_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[70] = icmp_id
+
+class icmp_type(bsn_tlv):
+    type = 68
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmp_type()
+        _type = reader.read("!H")[0]
+        assert(_type == 68)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmp_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[68] = icmp_type
+
+class idle_notification(bsn_tlv):
+    type = 7
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = idle_notification()
+        _type = reader.read("!H")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("idle_notification {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[7] = idle_notification
+
+class idle_time(bsn_tlv):
+    type = 5
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = idle_time()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("idle_time {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[5] = idle_time
+
+class idle_timeout(bsn_tlv):
+    type = 8
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = idle_timeout()
+        _type = reader.read("!H")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("idle_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[8] = idle_timeout
+
+class igmp_snooping(bsn_tlv):
+    type = 78
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = igmp_snooping()
+        _type = reader.read("!H")[0]
+        assert(_type == 78)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("igmp_snooping {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[78] = igmp_snooping
+
+class internal_gateway_mac(bsn_tlv):
+    type = 28
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = internal_gateway_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 28)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("internal_gateway_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[28] = internal_gateway_mac
+
+class internal_mac(bsn_tlv):
+    type = 27
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = internal_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 27)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("internal_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[27] = internal_mac
+
+class interval(bsn_tlv):
+    type = 58
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = interval()
+        _type = reader.read("!H")[0]
+        assert(_type == 58)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("interval {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[58] = interval
+
+class ip_proto(bsn_tlv):
+    type = 67
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto()
+        _type = reader.read("!H")[0]
+        assert(_type == 67)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[67] = ip_proto
+
+class ipv4(bsn_tlv):
+    type = 4
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[4] = ipv4
+
+class ipv4_dst(bsn_tlv):
+    type = 35
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 35)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[35] = ipv4_dst
+
+class ipv4_netmask(bsn_tlv):
+    type = 60
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_netmask()
+        _type = reader.read("!H")[0]
+        assert(_type == 60)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_netmask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[60] = ipv4_netmask
+
+class ipv4_src(bsn_tlv):
+    type = 34
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 34)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[34] = ipv4_src
+
+class l2_multicast_lookup(bsn_tlv):
+    type = 79
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = l2_multicast_lookup()
+        _type = reader.read("!H")[0]
+        assert(_type == 79)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("l2_multicast_lookup {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[79] = l2_multicast_lookup
+
+class mac(bsn_tlv):
+    type = 1
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[1] = mac
+
+class mac_mask(bsn_tlv):
+    type = 56
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mac_mask()
+        _type = reader.read("!H")[0]
+        assert(_type == 56)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mac_mask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[56] = mac_mask
+
+class miss_packets(bsn_tlv):
+    type = 13
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = miss_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("miss_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[13] = miss_packets
+
+class mpls_control_word(bsn_tlv):
+    type = 62
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_control_word()
+        _type = reader.read("!H")[0]
+        assert(_type == 62)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_control_word {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[62] = mpls_control_word
+
+class mpls_label(bsn_tlv):
+    type = 61
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label()
+        _type = reader.read("!H")[0]
+        assert(_type == 61)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[61] = mpls_label
+
+class mpls_sequenced(bsn_tlv):
+    type = 63
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_sequenced()
+        _type = reader.read("!H")[0]
+        assert(_type == 63)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_sequenced {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[63] = mpls_sequenced
+
+class name(bsn_tlv):
+    type = 52
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(self.value)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = name()
+        _type = reader.read("!H")[0]
+        assert(_type == 52)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("name {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[52] = name
+
+class offset(bsn_tlv):
+    type = 82
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = offset()
+        _type = reader.read("!H")[0]
+        assert(_type == 82)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("offset {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[82] = offset
+
+class partner_key(bsn_tlv):
+    type = 51
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_key()
+        _type = reader.read("!H")[0]
+        assert(_type == 51)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_key {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[51] = partner_key
+
+class partner_port_num(bsn_tlv):
+    type = 50
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_port_num()
+        _type = reader.read("!H")[0]
+        assert(_type == 50)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_port_num {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[50] = partner_port_num
+
+class partner_port_priority(bsn_tlv):
+    type = 49
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_port_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 49)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_port_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[49] = partner_port_priority
+
+class partner_state(bsn_tlv):
+    type = 54
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_state()
+        _type = reader.read("!H")[0]
+        assert(_type == 54)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_state {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[54] = partner_state
+
+class partner_system_mac(bsn_tlv):
+    type = 48
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_system_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 48)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_system_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[48] = partner_system_mac
+
+class partner_system_priority(bsn_tlv):
+    type = 47
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_system_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 47)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_system_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[47] = partner_system_priority
+
+class port(bsn_tlv):
+    type = 0
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(util.pack_port_no(self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[0] = port
+
+class priority(bsn_tlv):
+    type = 57
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 57)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[57] = priority
+
+class queue_id(bsn_tlv):
+    type = 20
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[20] = queue_id
+
+class queue_weight(bsn_tlv):
+    type = 21
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_weight()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_weight {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[21] = queue_weight
+
+class reference(bsn_tlv):
+    type = 59
+
+    def __init__(self, table_id=None, key=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = reference()
+        _type = reader.read("!H")[0]
+        assert(_type == 59)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.table_id = reader.read("!H")[0]
+        obj.key = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.key != other.key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("reference {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[59] = reference
+
+class reply_packets(bsn_tlv):
+    type = 12
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = reply_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("reply_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[12] = reply_packets
+
+class request_packets(bsn_tlv):
+    type = 11
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = request_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("request_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[11] = request_packets
+
+class rx_bytes(bsn_tlv):
+    type = 71
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = rx_bytes()
+        _type = reader.read("!H")[0]
+        assert(_type == 71)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("rx_bytes {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[71] = rx_bytes
+
+class rx_packets(bsn_tlv):
+    type = 2
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = rx_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("rx_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[2] = rx_packets
+
+class sampling_rate(bsn_tlv):
+    type = 30
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sampling_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 30)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sampling_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[30] = sampling_rate
+
+class set_loopback_mode(bsn_tlv):
+    type = 74
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_loopback_mode()
+        _type = reader.read("!H")[0]
+        assert(_type == 74)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_loopback_mode {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[74] = set_loopback_mode
+
+class strip_mpls_l2_on_ingress(bsn_tlv):
+    type = 75
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = strip_mpls_l2_on_ingress()
+        _type = reader.read("!H")[0]
+        assert(_type == 75)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("strip_mpls_l2_on_ingress {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[75] = strip_mpls_l2_on_ingress
+
+class strip_mpls_l3_on_ingress(bsn_tlv):
+    type = 76
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = strip_mpls_l3_on_ingress()
+        _type = reader.read("!H")[0]
+        assert(_type == 76)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("strip_mpls_l3_on_ingress {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[76] = strip_mpls_l3_on_ingress
+
+class strip_vlan_on_egress(bsn_tlv):
+    type = 73
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = strip_vlan_on_egress()
+        _type = reader.read("!H")[0]
+        assert(_type == 73)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("strip_vlan_on_egress {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[73] = strip_vlan_on_egress
+
+class sub_agent_id(bsn_tlv):
+    type = 38
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sub_agent_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 38)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sub_agent_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[38] = sub_agent_id
+
+class tcp_dst(bsn_tlv):
+    type = 66
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 66)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[66] = tcp_dst
+
+class tcp_src(bsn_tlv):
+    type = 65
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 65)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[65] = tcp_src
+
+class tx_bytes(bsn_tlv):
+    type = 39
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tx_bytes()
+        _type = reader.read("!H")[0]
+        assert(_type == 39)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tx_bytes {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[39] = tx_bytes
+
+class tx_packets(bsn_tlv):
+    type = 3
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tx_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tx_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[3] = tx_packets
+
+class udf_anchor(bsn_tlv):
+    type = 16
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_anchor()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_anchor {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[16] = udf_anchor
+
+class udf_id(bsn_tlv):
+    type = 15
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[15] = udf_id
+
+class udf_length(bsn_tlv):
+    type = 18
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_length()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_length {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[18] = udf_length
+
+class udf_offset(bsn_tlv):
+    type = 17
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_offset()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_offset {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[17] = udf_offset
+
+class udp_dst(bsn_tlv):
+    type = 37
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 37)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[37] = udp_dst
+
+class udp_src(bsn_tlv):
+    type = 36
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 36)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[36] = udp_src
+
+class unicast_query_timeout(bsn_tlv):
+    type = 9
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = unicast_query_timeout()
+        _type = reader.read("!H")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("unicast_query_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[9] = unicast_query_timeout
+
+class vlan_pcp(bsn_tlv):
+    type = 72
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp()
+        _type = reader.read("!H")[0]
+        assert(_type == 72)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[72] = vlan_pcp
+
+class vlan_vid(bsn_tlv):
+    type = 6
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[6] = vlan_vid
+
+class vlan_vid_mask(bsn_tlv):
+    type = 77
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid_mask()
+        _type = reader.read("!H")[0]
+        assert(_type == 77)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid_mask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[77] = vlan_vid_mask
+
+class vrf(bsn_tlv):
+    type = 19
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vrf()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vrf {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[19] = vrf
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of13/common.py b/Fabric/Utilities/src/python/loxi/of13/common.py
new file mode 100644
index 0000000..f5c06a4
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/common.py
@@ -0,0 +1,4066 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class bsn_controller_connection(loxi.OFObject):
+
+    def __init__(self, state=None, auxiliary_id=None, role=None, uri=None):
+        if state != None:
+            self.state = state
+        else:
+            self.state = 0
+        if auxiliary_id != None:
+            self.auxiliary_id = auxiliary_id
+        else:
+            self.auxiliary_id = 0
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if uri != None:
+            self.uri = uri
+        else:
+            self.uri = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.state))
+        packed.append(struct.pack("!B", self.auxiliary_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.role))
+        packed.append(struct.pack("!256s", self.uri))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_controller_connection()
+        obj.state = reader.read("!B")[0]
+        obj.auxiliary_id = reader.read("!B")[0]
+        reader.skip(2)
+        obj.role = reader.read("!L")[0]
+        obj.uri = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.state != other.state: return False
+        if self.auxiliary_id != other.auxiliary_id: return False
+        if self.role != other.role: return False
+        if self.uri != other.uri: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_controller_connection {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("state = ");
+                q.text("%#x" % self.state)
+                q.text(","); q.breakable()
+                q.text("auxiliary_id = ");
+                q.text("%#x" % self.auxiliary_id)
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("uri = ");
+                q.pp(self.uri)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_debug_counter_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, counter_id=None, name=None, description=None):
+        if counter_id != None:
+            self.counter_id = counter_id
+        else:
+            self.counter_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if description != None:
+            self.description = description
+        else:
+            self.description = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.counter_id))
+        packed.append(struct.pack("!64s", self.name))
+        packed.append(struct.pack("!256s", self.description))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_desc_stats_entry()
+        obj.counter_id = reader.read("!Q")[0]
+        obj.name = reader.read("!64s")[0].rstrip("\x00")
+        obj.description = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.counter_id != other.counter_id: return False
+        if self.name != other.name: return False
+        if self.description != other.description: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("counter_id = ");
+                q.text("%#x" % self.counter_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("description = ");
+                q.pp(self.description)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_debug_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, counter_id=None, value=None):
+        if counter_id != None:
+            self.counter_id = counter_id
+        else:
+            self.counter_id = 0
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.counter_id))
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_stats_entry()
+        obj.counter_id = reader.read("!Q")[0]
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.counter_id != other.counter_id: return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("counter_id = ");
+                q.text("%#x" % self.counter_id)
+                q.text(","); q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_flow_checksum_bucket_stats_entry(loxi.OFObject):
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_checksum_bucket_stats_entry()
+        obj.checksum = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_checksum_bucket_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.text("%#x" % self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_generic_stats_entry(loxi.OFObject):
+
+    def __init__(self, tlvs=None):
+        if tlvs != None:
+            self.tlvs = tlvs
+        else:
+            self.tlvs = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(loxi.generic_util.pack_list(self.tlvs))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generic_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.tlvs = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.tlvs != other.tlvs: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generic_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("tlvs = ");
+                q.pp(self.tlvs)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_bucket_stats_entry(loxi.OFObject):
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_checksum_128(self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_bucket_stats_entry()
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_bucket_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, name=None, buckets_size=None, max_entries=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if buckets_size != None:
+            self.buckets_size = buckets_size
+        else:
+            self.buckets_size = 0
+        if max_entries != None:
+            self.max_entries = max_entries
+        else:
+            self.max_entries = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(struct.pack("!32s", self.name))
+        packed.append(struct.pack("!L", self.buckets_size))
+        packed.append(struct.pack("!L", self.max_entries))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!H")[0]
+        obj.name = reader.read("!32s")[0].rstrip("\x00")
+        obj.buckets_size = reader.read("!L")[0]
+        obj.max_entries = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.name != other.name: return False
+        if self.buckets_size != other.buckets_size: return False
+        if self.max_entries != other.max_entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("buckets_size = ");
+                q.text("%#x" % self.buckets_size)
+                q.text(","); q.breakable()
+                q.text("max_entries = ");
+                q.text("%#x" % self.max_entries)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_entry_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, checksum=None, key=None, value=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        if value != None:
+            self.value = value
+        else:
+            self.value = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", 0)) # placeholder for key_length at index 1
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        packed[1] = struct.pack("!H", len(packed[-1]))
+        packed.append(loxi.generic_util.pack_list(self.value))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        _key_length = reader.read("!H")[0]
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.key = loxi.generic_util.unpack_list(reader.slice(_key_length), ofp.bsn_tlv.bsn_tlv.unpack)
+        obj.value = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        if self.key != other.key: return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+                q.text(","); q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_entry_stats_entry(loxi.OFObject):
+
+    def __init__(self, key=None, stats=None):
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        if stats != None:
+            self.stats = stats
+        else:
+            self.stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", 0)) # placeholder for key_length at index 1
+        packed.append(loxi.generic_util.pack_list(self.key))
+        packed[1] = struct.pack("!H", len(packed[-1]))
+        packed.append(loxi.generic_util.pack_list(self.stats))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        _key_length = reader.read("!H")[0]
+        obj.key = loxi.generic_util.unpack_list(reader.slice(_key_length), ofp.bsn_tlv.bsn_tlv.unpack)
+        obj.stats = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.key != other.key: return False
+        if self.stats != other.stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+                q.text(","); q.breakable()
+                q.text("stats = ");
+                q.pp(self.stats)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, entry_count=None, checksum=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if entry_count != None:
+            self.entry_count = entry_count
+        else:
+            self.entry_count = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.entry_count))
+        packed.append(util.pack_checksum_128(self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_stats_entry()
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.entry_count = reader.read("!L")[0]
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.entry_count != other.entry_count: return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("entry_count = ");
+                q.text("%#x" % self.entry_count)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_interface(loxi.OFObject):
+
+    def __init__(self, hw_addr=None, name=None, ipv4_addr=None, ipv4_netmask=None):
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if ipv4_addr != None:
+            self.ipv4_addr = ipv4_addr
+        else:
+            self.ipv4_addr = 0
+        if ipv4_netmask != None:
+            self.ipv4_netmask = ipv4_netmask
+        else:
+            self.ipv4_netmask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.ipv4_addr))
+        packed.append(struct.pack("!L", self.ipv4_netmask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_interface()
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.ipv4_addr = reader.read("!L")[0]
+        obj.ipv4_netmask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.ipv4_addr != other.ipv4_addr: return False
+        if self.ipv4_netmask != other.ipv4_netmask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_interface {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("ipv4_addr = ");
+                q.text(util.pretty_ipv4(self.ipv4_addr))
+                q.text(","); q.breakable()
+                q.text("ipv4_netmask = ");
+                q.text(util.pretty_ipv4(self.ipv4_netmask))
+            q.breakable()
+        q.text('}')
+
+
+class bsn_lacp_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, actor_sys_priority=None, actor_sys_mac=None, actor_port_priority=None, actor_port_num=None, actor_key=None, convergence_status=None, partner_sys_priority=None, partner_sys_mac=None, partner_port_priority=None, partner_port_num=None, partner_key=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if actor_sys_priority != None:
+            self.actor_sys_priority = actor_sys_priority
+        else:
+            self.actor_sys_priority = 0
+        if actor_sys_mac != None:
+            self.actor_sys_mac = actor_sys_mac
+        else:
+            self.actor_sys_mac = [0,0,0,0,0,0]
+        if actor_port_priority != None:
+            self.actor_port_priority = actor_port_priority
+        else:
+            self.actor_port_priority = 0
+        if actor_port_num != None:
+            self.actor_port_num = actor_port_num
+        else:
+            self.actor_port_num = 0
+        if actor_key != None:
+            self.actor_key = actor_key
+        else:
+            self.actor_key = 0
+        if convergence_status != None:
+            self.convergence_status = convergence_status
+        else:
+            self.convergence_status = 0
+        if partner_sys_priority != None:
+            self.partner_sys_priority = partner_sys_priority
+        else:
+            self.partner_sys_priority = 0
+        if partner_sys_mac != None:
+            self.partner_sys_mac = partner_sys_mac
+        else:
+            self.partner_sys_mac = [0,0,0,0,0,0]
+        if partner_port_priority != None:
+            self.partner_port_priority = partner_port_priority
+        else:
+            self.partner_port_priority = 0
+        if partner_port_num != None:
+            self.partner_port_num = partner_port_num
+        else:
+            self.partner_port_num = 0
+        if partner_key != None:
+            self.partner_key = partner_key
+        else:
+            self.partner_key = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!H", self.actor_sys_priority))
+        packed.append(struct.pack("!6B", *self.actor_sys_mac))
+        packed.append(struct.pack("!H", self.actor_port_priority))
+        packed.append(struct.pack("!H", self.actor_port_num))
+        packed.append(struct.pack("!H", self.actor_key))
+        packed.append(struct.pack("!B", self.convergence_status))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.partner_sys_priority))
+        packed.append(struct.pack("!6B", *self.partner_sys_mac))
+        packed.append(struct.pack("!H", self.partner_port_priority))
+        packed.append(struct.pack("!H", self.partner_port_num))
+        packed.append(struct.pack("!H", self.partner_key))
+        packed.append('\x00' * 2)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        obj.actor_sys_priority = reader.read("!H")[0]
+        obj.actor_sys_mac = list(reader.read('!6B'))
+        obj.actor_port_priority = reader.read("!H")[0]
+        obj.actor_port_num = reader.read("!H")[0]
+        obj.actor_key = reader.read("!H")[0]
+        obj.convergence_status = reader.read("!B")[0]
+        reader.skip(1)
+        obj.partner_sys_priority = reader.read("!H")[0]
+        obj.partner_sys_mac = list(reader.read('!6B'))
+        obj.partner_port_priority = reader.read("!H")[0]
+        obj.partner_port_num = reader.read("!H")[0]
+        obj.partner_key = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.actor_sys_priority != other.actor_sys_priority: return False
+        if self.actor_sys_mac != other.actor_sys_mac: return False
+        if self.actor_port_priority != other.actor_port_priority: return False
+        if self.actor_port_num != other.actor_port_num: return False
+        if self.actor_key != other.actor_key: return False
+        if self.convergence_status != other.convergence_status: return False
+        if self.partner_sys_priority != other.partner_sys_priority: return False
+        if self.partner_sys_mac != other.partner_sys_mac: return False
+        if self.partner_port_priority != other.partner_port_priority: return False
+        if self.partner_port_num != other.partner_port_num: return False
+        if self.partner_key != other.partner_key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("actor_sys_priority = ");
+                q.text("%#x" % self.actor_sys_priority)
+                q.text(","); q.breakable()
+                q.text("actor_sys_mac = ");
+                q.text(util.pretty_mac(self.actor_sys_mac))
+                q.text(","); q.breakable()
+                q.text("actor_port_priority = ");
+                q.text("%#x" % self.actor_port_priority)
+                q.text(","); q.breakable()
+                q.text("actor_port_num = ");
+                q.text("%#x" % self.actor_port_num)
+                q.text(","); q.breakable()
+                q.text("actor_key = ");
+                q.text("%#x" % self.actor_key)
+                q.text(","); q.breakable()
+                q.text("convergence_status = ");
+                q.text("%#x" % self.convergence_status)
+                q.text(","); q.breakable()
+                q.text("partner_sys_priority = ");
+                q.text("%#x" % self.partner_sys_priority)
+                q.text(","); q.breakable()
+                q.text("partner_sys_mac = ");
+                q.text(util.pretty_mac(self.partner_sys_mac))
+                q.text(","); q.breakable()
+                q.text("partner_port_priority = ");
+                q.text("%#x" % self.partner_port_priority)
+                q.text(","); q.breakable()
+                q.text("partner_port_num = ");
+                q.text("%#x" % self.partner_port_num)
+                q.text(","); q.breakable()
+                q.text("partner_key = ");
+                q.text("%#x" % self.partner_key)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_port_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, values=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if values != None:
+            self.values = values
+        else:
+            self.values = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(loxi.generic_util.pack_list(self.values))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_port_counter_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.values = loxi.generic_util.unpack_list(reader, ofp.common.uint64.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.values != other.values: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_port_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("values = ");
+                q.pp(self.values)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_switch_pipeline_stats_entry(loxi.OFObject):
+
+    def __init__(self, pipeline=None):
+        if pipeline != None:
+            self.pipeline = pipeline
+        else:
+            self.pipeline = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!256s", self.pipeline))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_switch_pipeline_stats_entry()
+        obj.pipeline = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.pipeline != other.pipeline: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_switch_pipeline_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("pipeline = ");
+                q.pp(self.pipeline)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_table_checksum_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, checksum=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!Q", self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_checksum_stats_entry()
+        obj.table_id = reader.read("!B")[0]
+        obj.checksum = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_checksum_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.text("%#x" % self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bsn_vport.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_vport()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vlan_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, vlan_vid=None, values=None):
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        if values != None:
+            self.values = values
+        else:
+            self.values = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.values))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_counter_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.vlan_vid = reader.read("!H")[0]
+        reader.skip(4)
+        obj.values = loxi.generic_util.unpack_list(reader, ofp.common.uint64.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vlan_vid != other.vlan_vid: return False
+        if self.values != other.values: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+                q.text(","); q.breakable()
+                q.text("values = ");
+                q.pp(self.values)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport_l2gre(bsn_vport):
+    type = 1
+
+    def __init__(self, flags=None, port_no=None, loopback_port_no=None, local_mac=None, nh_mac=None, src_ip=None, dst_ip=None, dscp=None, ttl=None, vpn=None, rate_limit=None, if_name=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if loopback_port_no != None:
+            self.loopback_port_no = loopback_port_no
+        else:
+            self.loopback_port_no = 0
+        if local_mac != None:
+            self.local_mac = local_mac
+        else:
+            self.local_mac = [0,0,0,0,0,0]
+        if nh_mac != None:
+            self.nh_mac = nh_mac
+        else:
+            self.nh_mac = [0,0,0,0,0,0]
+        if src_ip != None:
+            self.src_ip = src_ip
+        else:
+            self.src_ip = 0
+        if dst_ip != None:
+            self.dst_ip = dst_ip
+        else:
+            self.dst_ip = 0
+        if dscp != None:
+            self.dscp = dscp
+        else:
+            self.dscp = 0
+        if ttl != None:
+            self.ttl = ttl
+        else:
+            self.ttl = 0
+        if vpn != None:
+            self.vpn = vpn
+        else:
+            self.vpn = 0
+        if rate_limit != None:
+            self.rate_limit = rate_limit
+        else:
+            self.rate_limit = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.flags))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(util.pack_port_no(self.loopback_port_no))
+        packed.append(struct.pack("!6B", *self.local_mac))
+        packed.append(struct.pack("!6B", *self.nh_mac))
+        packed.append(struct.pack("!L", self.src_ip))
+        packed.append(struct.pack("!L", self.dst_ip))
+        packed.append(struct.pack("!B", self.dscp))
+        packed.append(struct.pack("!B", self.ttl))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.vpn))
+        packed.append(struct.pack("!L", self.rate_limit))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_l2gre()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.flags = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.loopback_port_no = util.unpack_port_no(reader)
+        obj.local_mac = list(reader.read('!6B'))
+        obj.nh_mac = list(reader.read('!6B'))
+        obj.src_ip = reader.read("!L")[0]
+        obj.dst_ip = reader.read("!L")[0]
+        obj.dscp = reader.read("!B")[0]
+        obj.ttl = reader.read("!B")[0]
+        reader.skip(2)
+        obj.vpn = reader.read("!L")[0]
+        obj.rate_limit = reader.read("!L")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.loopback_port_no != other.loopback_port_no: return False
+        if self.local_mac != other.local_mac: return False
+        if self.nh_mac != other.nh_mac: return False
+        if self.src_ip != other.src_ip: return False
+        if self.dst_ip != other.dst_ip: return False
+        if self.dscp != other.dscp: return False
+        if self.ttl != other.ttl: return False
+        if self.vpn != other.vpn: return False
+        if self.rate_limit != other.rate_limit: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_l2gre {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("loopback_port_no = ");
+                q.text(util.pretty_port(self.loopback_port_no))
+                q.text(","); q.breakable()
+                q.text("local_mac = ");
+                q.text(util.pretty_mac(self.local_mac))
+                q.text(","); q.breakable()
+                q.text("nh_mac = ");
+                q.text(util.pretty_mac(self.nh_mac))
+                q.text(","); q.breakable()
+                q.text("src_ip = ");
+                q.text(util.pretty_ipv4(self.src_ip))
+                q.text(","); q.breakable()
+                q.text("dst_ip = ");
+                q.text(util.pretty_ipv4(self.dst_ip))
+                q.text(","); q.breakable()
+                q.text("dscp = ");
+                q.text("%#x" % self.dscp)
+                q.text(","); q.breakable()
+                q.text("ttl = ");
+                q.text("%#x" % self.ttl)
+                q.text(","); q.breakable()
+                q.text("vpn = ");
+                q.text("%#x" % self.vpn)
+                q.text(","); q.breakable()
+                q.text("rate_limit = ");
+                q.text("%#x" % self.rate_limit)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[1] = bsn_vport_l2gre
+
+class bsn_vport_q_in_q(bsn_vport):
+    type = 0
+
+    def __init__(self, port_no=None, ingress_tpid=None, ingress_vlan_id=None, egress_tpid=None, egress_vlan_id=None, if_name=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if ingress_tpid != None:
+            self.ingress_tpid = ingress_tpid
+        else:
+            self.ingress_tpid = 0
+        if ingress_vlan_id != None:
+            self.ingress_vlan_id = ingress_vlan_id
+        else:
+            self.ingress_vlan_id = 0
+        if egress_tpid != None:
+            self.egress_tpid = egress_tpid
+        else:
+            self.egress_tpid = 0
+        if egress_vlan_id != None:
+            self.egress_vlan_id = egress_vlan_id
+        else:
+            self.egress_vlan_id = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.port_no))
+        packed.append(struct.pack("!H", self.ingress_tpid))
+        packed.append(struct.pack("!H", self.ingress_vlan_id))
+        packed.append(struct.pack("!H", self.egress_tpid))
+        packed.append(struct.pack("!H", self.egress_vlan_id))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_q_in_q()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.port_no = reader.read("!L")[0]
+        obj.ingress_tpid = reader.read("!H")[0]
+        obj.ingress_vlan_id = reader.read("!H")[0]
+        obj.egress_tpid = reader.read("!H")[0]
+        obj.egress_vlan_id = reader.read("!H")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.ingress_tpid != other.ingress_tpid: return False
+        if self.ingress_vlan_id != other.ingress_vlan_id: return False
+        if self.egress_tpid != other.egress_tpid: return False
+        if self.egress_vlan_id != other.egress_vlan_id: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_q_in_q {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text("%#x" % self.port_no)
+                q.text(","); q.breakable()
+                q.text("ingress_tpid = ");
+                q.text("%#x" % self.ingress_tpid)
+                q.text(","); q.breakable()
+                q.text("ingress_vlan_id = ");
+                q.text("%#x" % self.ingress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("egress_tpid = ");
+                q.text("%#x" % self.egress_tpid)
+                q.text(","); q.breakable()
+                q.text("egress_vlan_id = ");
+                q.text("%#x" % self.egress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[0] = bsn_vport_q_in_q
+
+class bsn_vrf_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, vrf=None, values=None):
+        if vrf != None:
+            self.vrf = vrf
+        else:
+            self.vrf = 0
+        if values != None:
+            self.values = values
+        else:
+            self.values = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.vrf))
+        packed.append(loxi.generic_util.pack_list(self.values))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_counter_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.vrf = reader.read("!L")[0]
+        obj.values = loxi.generic_util.unpack_list(reader, ofp.common.uint64.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vrf != other.vrf: return False
+        if self.values != other.values: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vrf = ");
+                q.text("%#x" % self.vrf)
+                q.text(","); q.breakable()
+                q.text("values = ");
+                q.pp(self.values)
+            q.breakable()
+        q.text('}')
+
+
+class bucket(loxi.OFObject):
+
+    def __init__(self, weight=None, watch_port=None, watch_group=None, actions=None):
+        if weight != None:
+            self.weight = weight
+        else:
+            self.weight = 0
+        if watch_port != None:
+            self.watch_port = watch_port
+        else:
+            self.watch_port = 0
+        if watch_group != None:
+            self.watch_group = watch_group
+        else:
+            self.watch_group = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 0
+        packed.append(struct.pack("!H", self.weight))
+        packed.append(util.pack_port_no(self.watch_port))
+        packed.append(struct.pack("!L", self.watch_group))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket()
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 2)
+        obj.weight = reader.read("!H")[0]
+        obj.watch_port = util.unpack_port_no(reader)
+        obj.watch_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.weight != other.weight: return False
+        if self.watch_port != other.watch_port: return False
+        if self.watch_group != other.watch_group: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("weight = ");
+                q.text("%#x" % self.weight)
+                q.text(","); q.breakable()
+                q.text("watch_port = ");
+                q.text(util.pretty_port(self.watch_port))
+                q.text(","); q.breakable()
+                q.text("watch_group = ");
+                q.text("%#x" % self.watch_group)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+
+class bucket_counter(loxi.OFObject):
+
+    def __init__(self, packet_count=None, byte_count=None):
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket_counter()
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket_counter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+            q.breakable()
+        q.text('}')
+
+
+class flow_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, duration_sec=None, duration_nsec=None, priority=None, idle_timeout=None, hard_timeout=None, flags=None, cookie=None, packet_count=None, byte_count=None, match=None, instructions=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.priority != other.priority: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.flags != other.flags: return False
+        if self.cookie != other.cookie: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+
+class group_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_type=None, group_id=None, buckets=None):
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+
+class group_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_id=None, ref_count=None, packet_count=None, byte_count=None, duration_sec=None, duration_nsec=None, bucket_stats=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if ref_count != None:
+            self.ref_count = ref_count
+        else:
+            self.ref_count = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if bucket_stats != None:
+            self.bucket_stats = bucket_stats
+        else:
+            self.bucket_stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(struct.pack("!L", self.ref_count))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(loxi.generic_util.pack_list(self.bucket_stats))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.group_id = reader.read("!L")[0]
+        obj.ref_count = reader.read("!L")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.bucket_stats = loxi.generic_util.unpack_list(reader, ofp.common.bucket_counter.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        if self.ref_count != other.ref_count: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.bucket_stats != other.bucket_stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("ref_count = ");
+                q.text("%#x" % self.ref_count)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("bucket_stats = ");
+                q.pp(self.bucket_stats)
+            q.breakable()
+        q.text('}')
+
+
+class hello_elem(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = hello_elem.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = hello_elem()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_elem {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class hello_elem_versionbitmap(hello_elem):
+    type = 1
+
+    def __init__(self, bitmaps=None):
+        if bitmaps != None:
+            self.bitmaps = bitmaps
+        else:
+            self.bitmaps = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.bitmaps))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello_elem_versionbitmap()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.bitmaps = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.bitmaps != other.bitmaps: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_elem_versionbitmap {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("bitmaps = ");
+                q.pp(self.bitmaps)
+            q.breakable()
+        q.text('}')
+
+hello_elem.subtypes[1] = hello_elem_versionbitmap
+
+class match_v3(loxi.OFObject):
+    type = 1
+
+    def __init__(self, oxm_list=None):
+        if oxm_list != None:
+            self.oxm_list = oxm_list
+        else:
+            self.oxm_list = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_list))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = match_v3()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_list = loxi.generic_util.unpack_list(reader, ofp.oxm.oxm.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_list != other.oxm_list: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("match_v3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_list = ");
+                q.pp(self.oxm_list)
+            q.breakable()
+        q.text('}')
+
+
+class meter_band_stats(loxi.OFObject):
+
+    def __init__(self, packet_band_count=None, byte_band_count=None):
+        if packet_band_count != None:
+            self.packet_band_count = packet_band_count
+        else:
+            self.packet_band_count = 0
+        if byte_band_count != None:
+            self.byte_band_count = byte_band_count
+        else:
+            self.byte_band_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.packet_band_count))
+        packed.append(struct.pack("!Q", self.byte_band_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_band_stats()
+        obj.packet_band_count = reader.read("!Q")[0]
+        obj.byte_band_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.packet_band_count != other.packet_band_count: return False
+        if self.byte_band_count != other.byte_band_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_band_stats {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("packet_band_count = ");
+                q.text("%#x" % self.packet_band_count)
+                q.text(","); q.breakable()
+                q.text("byte_band_count = ");
+                q.text("%#x" % self.byte_band_count)
+            q.breakable()
+        q.text('}')
+
+
+class meter_config(loxi.OFObject):
+
+    def __init__(self, flags=None, meter_id=None, entries=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_config()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.flags = reader.read("!H")[0]
+        obj.meter_id = reader.read("!L")[0]
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.meter_band.meter_band.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_config {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+
+class meter_features(loxi.OFObject):
+
+    def __init__(self, max_meter=None, band_types=None, capabilities=None, max_bands=None, max_color=None):
+        if max_meter != None:
+            self.max_meter = max_meter
+        else:
+            self.max_meter = 0
+        if band_types != None:
+            self.band_types = band_types
+        else:
+            self.band_types = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if max_bands != None:
+            self.max_bands = max_bands
+        else:
+            self.max_bands = 0
+        if max_color != None:
+            self.max_color = max_color
+        else:
+            self.max_color = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.max_meter))
+        packed.append(struct.pack("!L", self.band_types))
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!B", self.max_bands))
+        packed.append(struct.pack("!B", self.max_color))
+        packed.append('\x00' * 2)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_features()
+        obj.max_meter = reader.read("!L")[0]
+        obj.band_types = reader.read("!L")[0]
+        obj.capabilities = reader.read("!L")[0]
+        obj.max_bands = reader.read("!B")[0]
+        obj.max_color = reader.read("!B")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.max_meter != other.max_meter: return False
+        if self.band_types != other.band_types: return False
+        if self.capabilities != other.capabilities: return False
+        if self.max_bands != other.max_bands: return False
+        if self.max_color != other.max_color: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_features {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("max_meter = ");
+                q.text("%#x" % self.max_meter)
+                q.text(","); q.breakable()
+                q.text("band_types = ");
+                q.text("%#x" % self.band_types)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("max_bands = ");
+                q.text("%#x" % self.max_bands)
+                q.text(","); q.breakable()
+                q.text("max_color = ");
+                q.text("%#x" % self.max_color)
+            q.breakable()
+        q.text('}')
+
+
+class meter_stats(loxi.OFObject):
+
+    def __init__(self, meter_id=None, flow_count=None, packet_in_count=None, byte_in_count=None, duration_sec=None, duration_nsec=None, band_stats=None):
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        if flow_count != None:
+            self.flow_count = flow_count
+        else:
+            self.flow_count = 0
+        if packet_in_count != None:
+            self.packet_in_count = packet_in_count
+        else:
+            self.packet_in_count = 0
+        if byte_in_count != None:
+            self.byte_in_count = byte_in_count
+        else:
+            self.byte_in_count = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if band_stats != None:
+            self.band_stats = band_stats
+        else:
+            self.band_stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 6)
+        packed.append(struct.pack("!L", self.flow_count))
+        packed.append(struct.pack("!Q", self.packet_in_count))
+        packed.append(struct.pack("!Q", self.byte_in_count))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(loxi.generic_util.pack_list(self.band_stats))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_stats()
+        obj.meter_id = reader.read("!L")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 6)
+        reader.skip(6)
+        obj.flow_count = reader.read("!L")[0]
+        obj.packet_in_count = reader.read("!Q")[0]
+        obj.byte_in_count = reader.read("!Q")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.band_stats = loxi.generic_util.unpack_list(reader, ofp.common.meter_band_stats.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.meter_id != other.meter_id: return False
+        if self.flow_count != other.flow_count: return False
+        if self.packet_in_count != other.packet_in_count: return False
+        if self.byte_in_count != other.byte_in_count: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.band_stats != other.band_stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_stats {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+                q.text(","); q.breakable()
+                q.text("flow_count = ");
+                q.text("%#x" % self.flow_count)
+                q.text(","); q.breakable()
+                q.text("packet_in_count = ");
+                q.text("%#x" % self.packet_in_count)
+                q.text(","); q.breakable()
+                q.text("byte_in_count = ");
+                q.text("%#x" % self.byte_in_count)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("band_stats = ");
+                q.pp(self.band_stats)
+            q.breakable()
+        q.text('}')
+
+
+class packet_queue(loxi.OFObject):
+
+    def __init__(self, queue_id=None, port=None, properties=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 2
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_queue()
+        obj.queue_id = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 10)
+        reader.skip(6)
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.common.queue_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        if self.port != other.port: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class port_desc(loxi.OFObject):
+
+    def __init__(self, port_no=None, hw_addr=None, name=None, config=None, state=None, curr=None, advertised=None, supported=None, peer=None, curr_speed=None, max_speed=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if state != None:
+            self.state = state
+        else:
+            self.state = 0
+        if curr != None:
+            self.curr = curr
+        else:
+            self.curr = 0
+        if advertised != None:
+            self.advertised = advertised
+        else:
+            self.advertised = 0
+        if supported != None:
+            self.supported = supported
+        else:
+            self.supported = 0
+        if peer != None:
+            self.peer = peer
+        else:
+            self.peer = 0
+        if curr_speed != None:
+            self.curr_speed = curr_speed
+        else:
+            self.curr_speed = 0
+        if max_speed != None:
+            self.max_speed = max_speed
+        else:
+            self.max_speed = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.state))
+        packed.append(struct.pack("!L", self.curr))
+        packed.append(struct.pack("!L", self.advertised))
+        packed.append(struct.pack("!L", self.supported))
+        packed.append(struct.pack("!L", self.peer))
+        packed.append(struct.pack("!L", self.curr_speed))
+        packed.append(struct.pack("!L", self.max_speed))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.config = reader.read("!L")[0]
+        obj.state = reader.read("!L")[0]
+        obj.curr = reader.read("!L")[0]
+        obj.advertised = reader.read("!L")[0]
+        obj.supported = reader.read("!L")[0]
+        obj.peer = reader.read("!L")[0]
+        obj.curr_speed = reader.read("!L")[0]
+        obj.max_speed = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.config != other.config: return False
+        if self.state != other.state: return False
+        if self.curr != other.curr: return False
+        if self.advertised != other.advertised: return False
+        if self.supported != other.supported: return False
+        if self.peer != other.peer: return False
+        if self.curr_speed != other.curr_speed: return False
+        if self.max_speed != other.max_speed: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("state = ");
+                q.text("%#x" % self.state)
+                q.text(","); q.breakable()
+                q.text("curr = ");
+                q.text("%#x" % self.curr)
+                q.text(","); q.breakable()
+                q.text("advertised = ");
+                q.text("%#x" % self.advertised)
+                q.text(","); q.breakable()
+                q.text("supported = ");
+                q.text("%#x" % self.supported)
+                q.text(","); q.breakable()
+                q.text("peer = ");
+                q.text("%#x" % self.peer)
+                q.text(","); q.breakable()
+                q.text("curr_speed = ");
+                q.text("%#x" % self.curr_speed)
+                q.text(","); q.breakable()
+                q.text("max_speed = ");
+                q.text("%#x" % self.max_speed)
+            q.breakable()
+        q.text('}')
+
+
+class port_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, rx_packets=None, tx_packets=None, rx_bytes=None, tx_bytes=None, rx_dropped=None, tx_dropped=None, rx_errors=None, tx_errors=None, rx_frame_err=None, rx_over_err=None, rx_crc_err=None, collisions=None, duration_sec=None, duration_nsec=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if rx_packets != None:
+            self.rx_packets = rx_packets
+        else:
+            self.rx_packets = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if rx_bytes != None:
+            self.rx_bytes = rx_bytes
+        else:
+            self.rx_bytes = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if rx_dropped != None:
+            self.rx_dropped = rx_dropped
+        else:
+            self.rx_dropped = 0
+        if tx_dropped != None:
+            self.tx_dropped = tx_dropped
+        else:
+            self.tx_dropped = 0
+        if rx_errors != None:
+            self.rx_errors = rx_errors
+        else:
+            self.rx_errors = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        if rx_frame_err != None:
+            self.rx_frame_err = rx_frame_err
+        else:
+            self.rx_frame_err = 0
+        if rx_over_err != None:
+            self.rx_over_err = rx_over_err
+        else:
+            self.rx_over_err = 0
+        if rx_crc_err != None:
+            self.rx_crc_err = rx_crc_err
+        else:
+            self.rx_crc_err = 0
+        if collisions != None:
+            self.collisions = collisions
+        else:
+            self.collisions = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.rx_packets))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.rx_bytes))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.rx_dropped))
+        packed.append(struct.pack("!Q", self.tx_dropped))
+        packed.append(struct.pack("!Q", self.rx_errors))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        packed.append(struct.pack("!Q", self.rx_frame_err))
+        packed.append(struct.pack("!Q", self.rx_over_err))
+        packed.append(struct.pack("!Q", self.rx_crc_err))
+        packed.append(struct.pack("!Q", self.collisions))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.rx_packets = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.rx_bytes = reader.read("!Q")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.rx_dropped = reader.read("!Q")[0]
+        obj.tx_dropped = reader.read("!Q")[0]
+        obj.rx_errors = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        obj.rx_frame_err = reader.read("!Q")[0]
+        obj.rx_over_err = reader.read("!Q")[0]
+        obj.rx_crc_err = reader.read("!Q")[0]
+        obj.collisions = reader.read("!Q")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.rx_packets != other.rx_packets: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.rx_bytes != other.rx_bytes: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.rx_dropped != other.rx_dropped: return False
+        if self.tx_dropped != other.tx_dropped: return False
+        if self.rx_errors != other.rx_errors: return False
+        if self.tx_errors != other.tx_errors: return False
+        if self.rx_frame_err != other.rx_frame_err: return False
+        if self.rx_over_err != other.rx_over_err: return False
+        if self.rx_crc_err != other.rx_crc_err: return False
+        if self.collisions != other.collisions: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("rx_packets = ");
+                q.text("%#x" % self.rx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("rx_bytes = ");
+                q.text("%#x" % self.rx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("rx_dropped = ");
+                q.text("%#x" % self.rx_dropped)
+                q.text(","); q.breakable()
+                q.text("tx_dropped = ");
+                q.text("%#x" % self.tx_dropped)
+                q.text(","); q.breakable()
+                q.text("rx_errors = ");
+                q.text("%#x" % self.rx_errors)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+                q.text(","); q.breakable()
+                q.text("rx_frame_err = ");
+                q.text("%#x" % self.rx_frame_err)
+                q.text(","); q.breakable()
+                q.text("rx_over_err = ");
+                q.text("%#x" % self.rx_over_err)
+                q.text(","); q.breakable()
+                q.text("rx_crc_err = ");
+                q.text("%#x" % self.rx_crc_err)
+                q.text(","); q.breakable()
+                q.text("collisions = ");
+                q.text("%#x" % self.collisions)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = queue_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop_experimenter(queue_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append('\x00' * 4)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = queue_prop_experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop_experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        reader.skip(4)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[65535] = queue_prop_experimenter
+
+class queue_prop_max_rate(queue_prop):
+    type = 2
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_max_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_max_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[2] = queue_prop_max_rate
+
+class queue_prop_min_rate(queue_prop):
+    type = 1
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_min_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_min_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[1] = queue_prop_min_rate
+
+class queue_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, queue_id=None, tx_bytes=None, tx_packets=None, tx_errors=None, duration_sec=None, duration_nsec=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.tx_errors != other.tx_errors: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+            q.breakable()
+        q.text('}')
+
+
+class table_feature_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = table_feature_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_feature_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class table_feature_prop_apply_actions(table_feature_prop):
+    type = 6
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[6] = table_feature_prop_apply_actions
+
+class table_feature_prop_apply_actions_miss(table_feature_prop):
+    type = 7
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_actions_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_actions_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[7] = table_feature_prop_apply_actions_miss
+
+class table_feature_prop_apply_setfield(table_feature_prop):
+    type = 14
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_setfield()
+        _type = reader.read("!H")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_setfield {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[14] = table_feature_prop_apply_setfield
+
+class table_feature_prop_apply_setfield_miss(table_feature_prop):
+    type = 15
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_setfield_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_setfield_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[15] = table_feature_prop_apply_setfield_miss
+
+class table_feature_prop_experimenter(table_feature_prop):
+    subtypes = {}
+
+    type = 65534
+
+    def __init__(self, experimenter=None, subtype=None, experimenter_data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if experimenter_data != None:
+            self.experimenter_data = experimenter_data
+        else:
+            self.experimenter_data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.experimenter_data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = table_feature_prop_experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_feature_prop_experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65534)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.experimenter_data = str(reader.read_all())
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.experimenter_data != other.experimenter_data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("experimenter_data = ");
+                q.pp(self.experimenter_data)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[65534] = table_feature_prop_experimenter
+
+class table_feature_prop_experimenter_miss(table_feature_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, subtype=None, experimenter_data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if experimenter_data != None:
+            self.experimenter_data = experimenter_data
+        else:
+            self.experimenter_data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.experimenter_data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = table_feature_prop_experimenter_miss.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_feature_prop_experimenter_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.experimenter_data = str(reader.read_all())
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.experimenter_data != other.experimenter_data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_experimenter_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("experimenter_data = ");
+                q.pp(self.experimenter_data)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[65535] = table_feature_prop_experimenter_miss
+
+class table_feature_prop_instructions(table_feature_prop):
+    type = 0
+
+    def __init__(self, instruction_ids=None):
+        if instruction_ids != None:
+            self.instruction_ids = instruction_ids
+        else:
+            self.instruction_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.instruction_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_instructions()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.instruction_ids = loxi.generic_util.unpack_list(reader, ofp.instruction_id.instruction_id.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.instruction_ids != other.instruction_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_instructions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("instruction_ids = ");
+                q.pp(self.instruction_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[0] = table_feature_prop_instructions
+
+class table_feature_prop_instructions_miss(table_feature_prop):
+    type = 1
+
+    def __init__(self, instruction_ids=None):
+        if instruction_ids != None:
+            self.instruction_ids = instruction_ids
+        else:
+            self.instruction_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.instruction_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_instructions_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.instruction_ids = loxi.generic_util.unpack_list(reader, ofp.instruction_id.instruction_id.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.instruction_ids != other.instruction_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_instructions_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("instruction_ids = ");
+                q.pp(self.instruction_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[1] = table_feature_prop_instructions_miss
+
+class table_feature_prop_match(table_feature_prop):
+    type = 8
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_match()
+        _type = reader.read("!H")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_match {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[8] = table_feature_prop_match
+
+class table_feature_prop_next_tables(table_feature_prop):
+    type = 2
+
+    def __init__(self, next_table_ids=None):
+        if next_table_ids != None:
+            self.next_table_ids = next_table_ids
+        else:
+            self.next_table_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.next_table_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_next_tables()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.next_table_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint8.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.next_table_ids != other.next_table_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_next_tables {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("next_table_ids = ");
+                q.pp(self.next_table_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[2] = table_feature_prop_next_tables
+
+class table_feature_prop_next_tables_miss(table_feature_prop):
+    type = 3
+
+    def __init__(self, next_table_ids=None):
+        if next_table_ids != None:
+            self.next_table_ids = next_table_ids
+        else:
+            self.next_table_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.next_table_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_next_tables_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.next_table_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint8.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.next_table_ids != other.next_table_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_next_tables_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("next_table_ids = ");
+                q.pp(self.next_table_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[3] = table_feature_prop_next_tables_miss
+
+class table_feature_prop_wildcards(table_feature_prop):
+    type = 10
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_wildcards()
+        _type = reader.read("!H")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_wildcards {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[10] = table_feature_prop_wildcards
+
+class table_feature_prop_write_actions(table_feature_prop):
+    type = 4
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[4] = table_feature_prop_write_actions
+
+class table_feature_prop_write_actions_miss(table_feature_prop):
+    type = 5
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_actions_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_actions_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[5] = table_feature_prop_write_actions_miss
+
+class table_feature_prop_write_setfield(table_feature_prop):
+    type = 12
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_setfield()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_setfield {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[12] = table_feature_prop_write_setfield
+
+class table_feature_prop_write_setfield_miss(table_feature_prop):
+    type = 13
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_setfield_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_setfield_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[13] = table_feature_prop_write_setfield_miss
+
+class table_features(loxi.OFObject):
+
+    def __init__(self, table_id=None, name=None, metadata_match=None, metadata_write=None, config=None, max_entries=None, properties=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if metadata_match != None:
+            self.metadata_match = metadata_match
+        else:
+            self.metadata_match = 0
+        if metadata_write != None:
+            self.metadata_write = metadata_write
+        else:
+            self.metadata_write = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if max_entries != None:
+            self.max_entries = max_entries
+        else:
+            self.max_entries = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 5)
+        packed.append(struct.pack("!32s", self.name))
+        packed.append(struct.pack("!Q", self.metadata_match))
+        packed.append(struct.pack("!Q", self.metadata_write))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.max_entries))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(5)
+        obj.name = reader.read("!32s")[0].rstrip("\x00")
+        obj.metadata_match = reader.read("!Q")[0]
+        obj.metadata_write = reader.read("!Q")[0]
+        obj.config = reader.read("!L")[0]
+        obj.max_entries = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.common.table_feature_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.name != other.name: return False
+        if self.metadata_match != other.metadata_match: return False
+        if self.metadata_write != other.metadata_write: return False
+        if self.config != other.config: return False
+        if self.max_entries != other.max_entries: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("metadata_match = ");
+                q.text("%#x" % self.metadata_match)
+                q.text(","); q.breakable()
+                q.text("metadata_write = ");
+                q.text("%#x" % self.metadata_write)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("max_entries = ");
+                q.text("%#x" % self.max_entries)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class table_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, active_count=None, lookup_count=None, matched_count=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if active_count != None:
+            self.active_count = active_count
+        else:
+            self.active_count = 0
+        if lookup_count != None:
+            self.lookup_count = lookup_count
+        else:
+            self.lookup_count = 0
+        if matched_count != None:
+            self.matched_count = matched_count
+        else:
+            self.matched_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.active_count))
+        packed.append(struct.pack("!Q", self.lookup_count))
+        packed.append(struct.pack("!Q", self.matched_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_entry()
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.active_count = reader.read("!L")[0]
+        obj.lookup_count = reader.read("!Q")[0]
+        obj.matched_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.active_count != other.active_count: return False
+        if self.lookup_count != other.lookup_count: return False
+        if self.matched_count != other.matched_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("active_count = ");
+                q.text("%#x" % self.active_count)
+                q.text(","); q.breakable()
+                q.text("lookup_count = ");
+                q.text("%#x" % self.lookup_count)
+                q.text(","); q.breakable()
+                q.text("matched_count = ");
+                q.text("%#x" % self.matched_count)
+            q.breakable()
+        q.text('}')
+
+
+class uint32(loxi.OFObject):
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = uint32()
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("uint32 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+class uint64(loxi.OFObject):
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = uint64()
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("uint64 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+class uint8(loxi.OFObject):
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = uint8()
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("uint8 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+
+match = match_v3
diff --git a/Fabric/Utilities/src/python/loxi/of13/const.py b/Fabric/Utilities/src/python/loxi/of13/const.py
new file mode 100644
index 0000000..f6a68eb
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/const.py
@@ -0,0 +1,1293 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template const.py
+# Do not modify
+
+OFP_VERSION = 4
+
+# Identifiers from group macro_definitions
+OFP_MAX_TABLE_NAME_LEN = 32
+OFP_MAX_PORT_NAME_LEN = 16
+OFP_TCP_PORT = 6653
+OFP_SSL_PORT = 6653
+OFP_ETH_ALEN = 6
+OFP_DEFAULT_MISS_SEND_LEN = 128
+OFP_VLAN_NONE = 0
+OFP_FLOW_PERMANENT = 0
+OFP_DEFAULT_PRIORITY = 32768
+OFP_NO_BUFFER = 4294967295
+DESC_STR_LEN = 256
+SERIAL_NUM_LEN = 32
+OFPQ_ALL = 4294967295
+OFPQ_MAX_RATE_UNCFG = 65535
+OFPQ_MIN_RATE_UNCFG = 65535
+
+# Identifiers from group of_bsn_lacp_convergence_status
+LACP_SUCCESS = 0
+LACP_TIMEDOUT = 1
+LACP_OUT_OF_SYNC = 2
+
+of_bsn_lacp_convergence_status_map = {
+    0: 'LACP_SUCCESS',
+    1: 'LACP_TIMEDOUT',
+    2: 'LACP_OUT_OF_SYNC',
+}
+
+# Identifiers from group of_bsn_pdu_slot_num
+BSN_PDU_SLOT_NUM_ANY = 255
+
+of_bsn_pdu_slot_num_map = {
+    255: 'BSN_PDU_SLOT_NUM_ANY',
+}
+
+# Identifiers from group of_bsn_vlan_counter
+OFP_BSN_VLAN_COUNTER_RX_BYTES = 0
+OFP_BSN_VLAN_COUNTER_RX_PACKETS = 1
+OFP_BSN_VLAN_COUNTER_TX_BYTES = 2
+OFP_BSN_VLAN_COUNTER_TX_PACKETS = 3
+
+of_bsn_vlan_counter_map = {
+    0: 'OFP_BSN_VLAN_COUNTER_RX_BYTES',
+    1: 'OFP_BSN_VLAN_COUNTER_RX_PACKETS',
+    2: 'OFP_BSN_VLAN_COUNTER_TX_BYTES',
+    3: 'OFP_BSN_VLAN_COUNTER_TX_PACKETS',
+}
+
+# Identifiers from group of_bsn_vrf_counter
+OFP_BSN_VRF_COUNTER_BYTES = 0
+OFP_BSN_VRF_COUNTER_PACKETS = 1
+
+of_bsn_vrf_counter_map = {
+    0: 'OFP_BSN_VRF_COUNTER_BYTES',
+    1: 'OFP_BSN_VRF_COUNTER_PACKETS',
+}
+
+# Identifiers from group ofp_action_type
+OFPAT_OUTPUT = 0
+OFPAT_COPY_TTL_OUT = 11
+OFPAT_COPY_TTL_IN = 12
+OFPAT_SET_MPLS_TTL = 15
+OFPAT_DEC_MPLS_TTL = 16
+OFPAT_PUSH_VLAN = 17
+OFPAT_POP_VLAN = 18
+OFPAT_PUSH_MPLS = 19
+OFPAT_POP_MPLS = 20
+OFPAT_SET_QUEUE = 21
+OFPAT_GROUP = 22
+OFPAT_SET_NW_TTL = 23
+OFPAT_DEC_NW_TTL = 24
+OFPAT_SET_FIELD = 25
+OFPAT_PUSH_PBB = 26
+OFPAT_POP_PBB = 27
+OFPAT_EXPERIMENTER = 65535
+
+ofp_action_type_map = {
+    0: 'OFPAT_OUTPUT',
+    11: 'OFPAT_COPY_TTL_OUT',
+    12: 'OFPAT_COPY_TTL_IN',
+    15: 'OFPAT_SET_MPLS_TTL',
+    16: 'OFPAT_DEC_MPLS_TTL',
+    17: 'OFPAT_PUSH_VLAN',
+    18: 'OFPAT_POP_VLAN',
+    19: 'OFPAT_PUSH_MPLS',
+    20: 'OFPAT_POP_MPLS',
+    21: 'OFPAT_SET_QUEUE',
+    22: 'OFPAT_GROUP',
+    23: 'OFPAT_SET_NW_TTL',
+    24: 'OFPAT_DEC_NW_TTL',
+    25: 'OFPAT_SET_FIELD',
+    26: 'OFPAT_PUSH_PBB',
+    27: 'OFPAT_POP_PBB',
+    65535: 'OFPAT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_bad_action_code
+OFPBAC_BAD_TYPE = 0
+OFPBAC_BAD_LEN = 1
+OFPBAC_BAD_EXPERIMENTER = 2
+OFPBAC_BAD_EXPERIMENTER_TYPE = 3
+OFPBAC_BAD_OUT_PORT = 4
+OFPBAC_BAD_ARGUMENT = 5
+OFPBAC_EPERM = 6
+OFPBAC_TOO_MANY = 7
+OFPBAC_BAD_QUEUE = 8
+OFPBAC_BAD_OUT_GROUP = 9
+OFPBAC_MATCH_INCONSISTENT = 10
+OFPBAC_UNSUPPORTED_ORDER = 11
+OFPBAC_BAD_TAG = 12
+OFPBAC_BAD_SET_TYPE = 13
+OFPBAC_BAD_SET_LEN = 14
+OFPBAC_BAD_SET_ARGUMENT = 15
+
+ofp_bad_action_code_map = {
+    0: 'OFPBAC_BAD_TYPE',
+    1: 'OFPBAC_BAD_LEN',
+    2: 'OFPBAC_BAD_EXPERIMENTER',
+    3: 'OFPBAC_BAD_EXPERIMENTER_TYPE',
+    4: 'OFPBAC_BAD_OUT_PORT',
+    5: 'OFPBAC_BAD_ARGUMENT',
+    6: 'OFPBAC_EPERM',
+    7: 'OFPBAC_TOO_MANY',
+    8: 'OFPBAC_BAD_QUEUE',
+    9: 'OFPBAC_BAD_OUT_GROUP',
+    10: 'OFPBAC_MATCH_INCONSISTENT',
+    11: 'OFPBAC_UNSUPPORTED_ORDER',
+    12: 'OFPBAC_BAD_TAG',
+    13: 'OFPBAC_BAD_SET_TYPE',
+    14: 'OFPBAC_BAD_SET_LEN',
+    15: 'OFPBAC_BAD_SET_ARGUMENT',
+}
+
+# Identifiers from group ofp_bad_instruction_code
+OFPBIC_UNKNOWN_INST = 0
+OFPBIC_UNSUP_INST = 1
+OFPBIC_BAD_TABLE_ID = 2
+OFPBIC_UNSUP_METADATA = 3
+OFPBIC_UNSUP_METADATA_MASK = 4
+OFPBIC_BAD_EXPERIMENTER = 5
+OFPBIC_BAD_EXPERIMENTER_TYPE = 6
+OFPBIC_BAD_LEN = 7
+OFPBIC_EPERM = 8
+
+ofp_bad_instruction_code_map = {
+    0: 'OFPBIC_UNKNOWN_INST',
+    1: 'OFPBIC_UNSUP_INST',
+    2: 'OFPBIC_BAD_TABLE_ID',
+    3: 'OFPBIC_UNSUP_METADATA',
+    4: 'OFPBIC_UNSUP_METADATA_MASK',
+    5: 'OFPBIC_BAD_EXPERIMENTER',
+    6: 'OFPBIC_BAD_EXPERIMENTER_TYPE',
+    7: 'OFPBIC_BAD_LEN',
+    8: 'OFPBIC_EPERM',
+}
+
+# Identifiers from group ofp_bad_match_code
+OFPBMC_BAD_TYPE = 0
+OFPBMC_BAD_LEN = 1
+OFPBMC_BAD_TAG = 2
+OFPBMC_BAD_DL_ADDR_MASK = 3
+OFPBMC_BAD_NW_ADDR_MASK = 4
+OFPBMC_BAD_WILDCARDS = 5
+OFPBMC_BAD_FIELD = 6
+OFPBMC_BAD_VALUE = 7
+OFPBMC_BAD_MASK = 8
+OFPBMC_BAD_PREREQ = 9
+OFPBMC_DUP_FIELD = 10
+OFPBMC_EPERM = 11
+
+ofp_bad_match_code_map = {
+    0: 'OFPBMC_BAD_TYPE',
+    1: 'OFPBMC_BAD_LEN',
+    2: 'OFPBMC_BAD_TAG',
+    3: 'OFPBMC_BAD_DL_ADDR_MASK',
+    4: 'OFPBMC_BAD_NW_ADDR_MASK',
+    5: 'OFPBMC_BAD_WILDCARDS',
+    6: 'OFPBMC_BAD_FIELD',
+    7: 'OFPBMC_BAD_VALUE',
+    8: 'OFPBMC_BAD_MASK',
+    9: 'OFPBMC_BAD_PREREQ',
+    10: 'OFPBMC_DUP_FIELD',
+    11: 'OFPBMC_EPERM',
+}
+
+# Identifiers from group ofp_bad_request_code
+OFPBRC_BAD_VERSION = 0
+OFPBRC_BAD_TYPE = 1
+OFPBRC_BAD_STAT = 2
+OFPBRC_BAD_EXPERIMENTER = 3
+OFPBRC_BAD_EXPERIMENTER_TYPE = 4
+OFPBRC_EPERM = 5
+OFPBRC_BAD_LEN = 6
+OFPBRC_BUFFER_EMPTY = 7
+OFPBRC_BUFFER_UNKNOWN = 8
+OFPBRC_BAD_TABLE_ID = 9
+OFPBRC_IS_SLAVE = 10
+OFPBRC_BAD_PORT = 11
+OFPBRC_BAD_PACKET = 12
+OFPBRC_MULTIPART_BUFFER_OVERFLOW = 13
+
+ofp_bad_request_code_map = {
+    0: 'OFPBRC_BAD_VERSION',
+    1: 'OFPBRC_BAD_TYPE',
+    2: 'OFPBRC_BAD_STAT',
+    3: 'OFPBRC_BAD_EXPERIMENTER',
+    4: 'OFPBRC_BAD_EXPERIMENTER_TYPE',
+    5: 'OFPBRC_EPERM',
+    6: 'OFPBRC_BAD_LEN',
+    7: 'OFPBRC_BUFFER_EMPTY',
+    8: 'OFPBRC_BUFFER_UNKNOWN',
+    9: 'OFPBRC_BAD_TABLE_ID',
+    10: 'OFPBRC_IS_SLAVE',
+    11: 'OFPBRC_BAD_PORT',
+    12: 'OFPBRC_BAD_PACKET',
+    13: 'OFPBRC_MULTIPART_BUFFER_OVERFLOW',
+}
+
+# Identifiers from group ofp_bsn_anchor
+OFP_BSN_ANCHOR_PACKET_START = 0
+OFP_BSN_ANCHOR_L3_HEADER_START = 1
+OFP_BSN_ANCHOR_L4_HEADER_START = 2
+OFP_BSN_ANCHOR_L4_PAYLOAD_START = 3
+
+ofp_bsn_anchor_map = {
+    0: 'OFP_BSN_ANCHOR_PACKET_START',
+    1: 'OFP_BSN_ANCHOR_L3_HEADER_START',
+    2: 'OFP_BSN_ANCHOR_L4_HEADER_START',
+    3: 'OFP_BSN_ANCHOR_L4_PAYLOAD_START',
+}
+
+# Identifiers from group ofp_bsn_controller_connection_state
+OFP_BSN_CONTROLLER_CONNECTION_STATE_DISCONNECTED = 0
+OFP_BSN_CONTROLLER_CONNECTION_STATE_CONNECTED = 1
+
+ofp_bsn_controller_connection_state_map = {
+    0: 'OFP_BSN_CONTROLLER_CONNECTION_STATE_DISCONNECTED',
+    1: 'OFP_BSN_CONTROLLER_CONNECTION_STATE_CONNECTED',
+}
+
+# Identifiers from group ofp_bsn_controller_role_reason
+OFP_BSN_CONTROLLER_ROLE_REASON_MASTER_REQUEST = 0
+OFP_BSN_CONTROLLER_ROLE_REASON_CONFIG = 1
+OFP_BSN_CONTROLLER_ROLE_REASON_EXPERIMENTER = 2
+
+ofp_bsn_controller_role_reason_map = {
+    0: 'OFP_BSN_CONTROLLER_ROLE_REASON_MASTER_REQUEST',
+    1: 'OFP_BSN_CONTROLLER_ROLE_REASON_CONFIG',
+    2: 'OFP_BSN_CONTROLLER_ROLE_REASON_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_bsn_lacp_state
+OFP_BSN_LACP_STATE_ACTIVITY = 1
+OFP_BSN_LACP_STATE_TIMEOUT = 2
+OFP_BSN_LACP_STATE_AGGREGATION = 4
+OFP_BSN_LACP_STATE_SYNCHRONIZATION = 8
+OFP_BSN_LACP_STATE_COLLECTING = 16
+OFP_BSN_LACP_STATE_DISTRIBUTING = 32
+OFP_BSN_LACP_STATE_DEFAULTED = 64
+OFP_BSN_LACP_STATE_EXPIRED = 128
+
+ofp_bsn_lacp_state_map = {
+    1: 'OFP_BSN_LACP_STATE_ACTIVITY',
+    2: 'OFP_BSN_LACP_STATE_TIMEOUT',
+    4: 'OFP_BSN_LACP_STATE_AGGREGATION',
+    8: 'OFP_BSN_LACP_STATE_SYNCHRONIZATION',
+    16: 'OFP_BSN_LACP_STATE_COLLECTING',
+    32: 'OFP_BSN_LACP_STATE_DISTRIBUTING',
+    64: 'OFP_BSN_LACP_STATE_DEFAULTED',
+    128: 'OFP_BSN_LACP_STATE_EXPIRED',
+}
+
+# Identifiers from group ofp_bsn_loglevel
+OFP_BSN_LOGLEVEL_MSG = 0
+OFP_BSN_LOGLEVEL_ERROR = 1
+OFP_BSN_LOGLEVEL_WARN = 2
+OFP_BSN_LOGLEVEL_INFO = 3
+OFP_BSN_LOGLEVEL_VERBOSE = 4
+OFP_BSN_LOGLEVEL_TRACE = 5
+
+ofp_bsn_loglevel_map = {
+    0: 'OFP_BSN_LOGLEVEL_MSG',
+    1: 'OFP_BSN_LOGLEVEL_ERROR',
+    2: 'OFP_BSN_LOGLEVEL_WARN',
+    3: 'OFP_BSN_LOGLEVEL_INFO',
+    4: 'OFP_BSN_LOGLEVEL_VERBOSE',
+    5: 'OFP_BSN_LOGLEVEL_TRACE',
+}
+
+# Identifiers from group ofp_bsn_lua_upload_flags
+OFP_BSN_LUA_UPLOAD_MORE = 1
+OFP_BSN_LUA_UPLOAD_FORCE = 2
+
+ofp_bsn_lua_upload_flags_map = {
+    1: 'OFP_BSN_LUA_UPLOAD_MORE',
+    2: 'OFP_BSN_LUA_UPLOAD_FORCE',
+}
+
+# Identifiers from group ofp_bsn_pktin_flag
+OFP_BSN_PKTIN_FLAG_PDU = 1
+OFP_BSN_PKTIN_FLAG_NEW_HOST = 2
+OFP_BSN_PKTIN_FLAG_STATION_MOVE = 4
+OFP_BSN_PKTIN_FLAG_ARP = 8
+OFP_BSN_PKTIN_FLAG_DHCP = 16
+OFP_BSN_PKTIN_FLAG_L2_CPU = 32
+OFP_BSN_PKTIN_FLAG_DEBUG = 64
+OFP_BSN_PKTIN_FLAG_TTL_EXPIRED = 128
+OFP_BSN_PKTIN_FLAG_L3_MISS = 256
+OFP_BSN_PKTIN_FLAG_L3_CPU = 512
+OFP_BSN_PKTIN_FLAG_INGRESS_ACL = 1024
+OFP_BSN_PKTIN_FLAG_SFLOW = 2048
+OFP_BSN_PKTIN_FLAG_ARP_CACHE = 4096
+OFP_BSN_PKTIN_FLAG_ARP_TARGET = 8192
+
+ofp_bsn_pktin_flag_map = {
+    1: 'OFP_BSN_PKTIN_FLAG_PDU',
+    2: 'OFP_BSN_PKTIN_FLAG_NEW_HOST',
+    4: 'OFP_BSN_PKTIN_FLAG_STATION_MOVE',
+    8: 'OFP_BSN_PKTIN_FLAG_ARP',
+    16: 'OFP_BSN_PKTIN_FLAG_DHCP',
+    32: 'OFP_BSN_PKTIN_FLAG_L2_CPU',
+    64: 'OFP_BSN_PKTIN_FLAG_DEBUG',
+    128: 'OFP_BSN_PKTIN_FLAG_TTL_EXPIRED',
+    256: 'OFP_BSN_PKTIN_FLAG_L3_MISS',
+    512: 'OFP_BSN_PKTIN_FLAG_L3_CPU',
+    1024: 'OFP_BSN_PKTIN_FLAG_INGRESS_ACL',
+    2048: 'OFP_BSN_PKTIN_FLAG_SFLOW',
+    4096: 'OFP_BSN_PKTIN_FLAG_ARP_CACHE',
+    8192: 'OFP_BSN_PKTIN_FLAG_ARP_TARGET',
+}
+
+# Identifiers from group ofp_bsn_port_counter
+OFP_BSN_PORT_COUNTER_RX_BYTES = 0
+OFP_BSN_PORT_COUNTER_RX_PACKETS_UNICAST = 1
+OFP_BSN_PORT_COUNTER_RX_PACKETS_BROADCAST = 2
+OFP_BSN_PORT_COUNTER_RX_PACKETS_MULTICAST = 3
+OFP_BSN_PORT_COUNTER_RX_DROPPED = 4
+OFP_BSN_PORT_COUNTER_RX_ERRORS = 5
+OFP_BSN_PORT_COUNTER_TX_BYTES = 6
+OFP_BSN_PORT_COUNTER_TX_PACKETS_UNICAST = 7
+OFP_BSN_PORT_COUNTER_TX_PACKETS_BROADCAST = 8
+OFP_BSN_PORT_COUNTER_TX_PACKETS_MULTICAST = 9
+OFP_BSN_PORT_COUNTER_TX_DROPPED = 10
+OFP_BSN_PORT_COUNTER_TX_ERRORS = 11
+OFP_BSN_PORT_COUNTER_RX_RUNTS = 12
+OFP_BSN_PORT_COUNTER_RX_GIANTS = 13
+OFP_BSN_PORT_COUNTER_RX_CRC_ERRORS = 14
+OFP_BSN_PORT_COUNTER_RX_ALIGNMENT_ERRORS = 15
+OFP_BSN_PORT_COUNTER_RX_SYMBOL_ERRORS = 16
+OFP_BSN_PORT_COUNTER_RX_PAUSE_INPUT = 17
+OFP_BSN_PORT_COUNTER_TX_COLLISIONS = 18
+OFP_BSN_PORT_COUNTER_TX_LATE_COLLISIONS = 19
+OFP_BSN_PORT_COUNTER_TX_DEFERRED = 20
+OFP_BSN_PORT_COUNTER_TX_PAUSE_OUTPUT = 21
+OFP_BSN_PORT_COUNTER_RX_PACKETS = 22
+OFP_BSN_PORT_COUNTER_TX_PACKETS = 23
+OFP_BSN_PORT_COUNTER_RX_LENGTH_ERRORS = 24
+OFP_BSN_PORT_COUNTER_RX_OVERFLOW_ERRORS = 25
+OFP_BSN_PORT_COUNTER_TX_CARRIER_ERRORS = 26
+OFP_BSN_PORT_COUNTER_RX_PACKETS_BAD_VLAN = 27
+
+ofp_bsn_port_counter_map = {
+    0: 'OFP_BSN_PORT_COUNTER_RX_BYTES',
+    1: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_UNICAST',
+    2: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_BROADCAST',
+    3: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_MULTICAST',
+    4: 'OFP_BSN_PORT_COUNTER_RX_DROPPED',
+    5: 'OFP_BSN_PORT_COUNTER_RX_ERRORS',
+    6: 'OFP_BSN_PORT_COUNTER_TX_BYTES',
+    7: 'OFP_BSN_PORT_COUNTER_TX_PACKETS_UNICAST',
+    8: 'OFP_BSN_PORT_COUNTER_TX_PACKETS_BROADCAST',
+    9: 'OFP_BSN_PORT_COUNTER_TX_PACKETS_MULTICAST',
+    10: 'OFP_BSN_PORT_COUNTER_TX_DROPPED',
+    11: 'OFP_BSN_PORT_COUNTER_TX_ERRORS',
+    12: 'OFP_BSN_PORT_COUNTER_RX_RUNTS',
+    13: 'OFP_BSN_PORT_COUNTER_RX_GIANTS',
+    14: 'OFP_BSN_PORT_COUNTER_RX_CRC_ERRORS',
+    15: 'OFP_BSN_PORT_COUNTER_RX_ALIGNMENT_ERRORS',
+    16: 'OFP_BSN_PORT_COUNTER_RX_SYMBOL_ERRORS',
+    17: 'OFP_BSN_PORT_COUNTER_RX_PAUSE_INPUT',
+    18: 'OFP_BSN_PORT_COUNTER_TX_COLLISIONS',
+    19: 'OFP_BSN_PORT_COUNTER_TX_LATE_COLLISIONS',
+    20: 'OFP_BSN_PORT_COUNTER_TX_DEFERRED',
+    21: 'OFP_BSN_PORT_COUNTER_TX_PAUSE_OUTPUT',
+    22: 'OFP_BSN_PORT_COUNTER_RX_PACKETS',
+    23: 'OFP_BSN_PORT_COUNTER_TX_PACKETS',
+    24: 'OFP_BSN_PORT_COUNTER_RX_LENGTH_ERRORS',
+    25: 'OFP_BSN_PORT_COUNTER_RX_OVERFLOW_ERRORS',
+    26: 'OFP_BSN_PORT_COUNTER_TX_CARRIER_ERRORS',
+    27: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_BAD_VLAN',
+}
+
+# Identifiers from group ofp_bsn_tcp_flag
+OFP_BSN_TCP_FLAG_FIN = 1
+OFP_BSN_TCP_FLAG_SYN = 2
+OFP_BSN_TCP_FLAG_RST = 4
+OFP_BSN_TCP_FLAG_PSH = 8
+OFP_BSN_TCP_FLAG_ACK = 16
+OFP_BSN_TCP_FLAG_URG = 32
+OFP_BSN_TCP_FLAG_ECE = 64
+OFP_BSN_TCP_FLAG_CWR = 128
+OFP_BSN_TCP_FLAG_NS = 256
+
+ofp_bsn_tcp_flag_map = {
+    1: 'OFP_BSN_TCP_FLAG_FIN',
+    2: 'OFP_BSN_TCP_FLAG_SYN',
+    4: 'OFP_BSN_TCP_FLAG_RST',
+    8: 'OFP_BSN_TCP_FLAG_PSH',
+    16: 'OFP_BSN_TCP_FLAG_ACK',
+    32: 'OFP_BSN_TCP_FLAG_URG',
+    64: 'OFP_BSN_TCP_FLAG_ECE',
+    128: 'OFP_BSN_TCP_FLAG_CWR',
+    256: 'OFP_BSN_TCP_FLAG_NS',
+}
+
+# Identifiers from group ofp_bsn_udf_anchor
+OFP_BSN_UDF_ANCHOR_PACKET_START = 0
+OFP_BSN_UDF_ANCHOR_L3_HEADER_START = 1
+OFP_BSN_UDF_ANCHOR_L4_HEADER_START = 2
+
+ofp_bsn_udf_anchor_map = {
+    0: 'OFP_BSN_UDF_ANCHOR_PACKET_START',
+    1: 'OFP_BSN_UDF_ANCHOR_L3_HEADER_START',
+    2: 'OFP_BSN_UDF_ANCHOR_L4_HEADER_START',
+}
+
+# Identifiers from group ofp_bsn_vlan_counter_constants
+OFP_BSN_VLAN_ALL = 65535
+
+ofp_bsn_vlan_counter_constants_map = {
+    65535: 'OFP_BSN_VLAN_ALL',
+}
+
+# Identifiers from group ofp_bsn_vport_l2gre_flags
+OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID = 1
+OF_BSN_VPORT_L2GRE_DSCP_ASSIGN = 2
+OF_BSN_VPORT_L2GRE_DSCP_COPY = 4
+OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID = 8
+OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID = 16
+
+ofp_bsn_vport_l2gre_flags_map = {
+    1: 'OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID',
+    2: 'OF_BSN_VPORT_L2GRE_DSCP_ASSIGN',
+    4: 'OF_BSN_VPORT_L2GRE_DSCP_COPY',
+    8: 'OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID',
+    16: 'OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID',
+}
+
+# Identifiers from group ofp_bsn_vport_q_in_q_untagged
+OF_BSN_VPORT_Q_IN_Q_UNTAGGED = 65535
+
+ofp_bsn_vport_q_in_q_untagged_map = {
+    65535: 'OF_BSN_VPORT_Q_IN_Q_UNTAGGED',
+}
+
+# Identifiers from group ofp_bsn_vport_status
+OF_BSN_VPORT_STATUS_OK = 0
+OF_BSN_VPORT_STATUS_FAILED = 1
+
+ofp_bsn_vport_status_map = {
+    0: 'OF_BSN_VPORT_STATUS_OK',
+    1: 'OF_BSN_VPORT_STATUS_FAILED',
+}
+
+# Identifiers from group ofp_bsn_vrf_counter_constants
+OFP_BSN_VRF_ALL = 4294967295
+
+ofp_bsn_vrf_counter_constants_map = {
+    4294967295: 'OFP_BSN_VRF_ALL',
+}
+
+# Identifiers from group ofp_capabilities
+OFPC_FLOW_STATS = 1
+OFPC_TABLE_STATS = 2
+OFPC_PORT_STATS = 4
+OFPC_GROUP_STATS = 8
+OFPC_IP_REASM = 32
+OFPC_QUEUE_STATS = 64
+OFPC_PORT_BLOCKED = 256
+
+ofp_capabilities_map = {
+    1: 'OFPC_FLOW_STATS',
+    2: 'OFPC_TABLE_STATS',
+    4: 'OFPC_PORT_STATS',
+    8: 'OFPC_GROUP_STATS',
+    32: 'OFPC_IP_REASM',
+    64: 'OFPC_QUEUE_STATS',
+    256: 'OFPC_PORT_BLOCKED',
+}
+
+# Identifiers from group ofp_config_flags
+OFPC_FRAG_NORMAL = 0
+OFPC_FRAG_DROP = 1
+OFPC_FRAG_REASM = 2
+OFPC_FRAG_MASK = 3
+
+ofp_config_flags_map = {
+    0: 'OFPC_FRAG_NORMAL',
+    1: 'OFPC_FRAG_DROP',
+    2: 'OFPC_FRAG_REASM',
+    3: 'OFPC_FRAG_MASK',
+}
+
+# Identifiers from group ofp_controller_max_len
+OFPCML_MAX = 65509
+OFPCML_NO_BUFFER = 65535
+
+ofp_controller_max_len_map = {
+    65509: 'OFPCML_MAX',
+    65535: 'OFPCML_NO_BUFFER',
+}
+
+# Identifiers from group ofp_controller_role
+OFPCR_ROLE_NOCHANGE = 0
+OFPCR_ROLE_EQUAL = 1
+OFPCR_ROLE_MASTER = 2
+OFPCR_ROLE_SLAVE = 3
+
+ofp_controller_role_map = {
+    0: 'OFPCR_ROLE_NOCHANGE',
+    1: 'OFPCR_ROLE_EQUAL',
+    2: 'OFPCR_ROLE_MASTER',
+    3: 'OFPCR_ROLE_SLAVE',
+}
+
+# Identifiers from group ofp_error_type
+OFPET_HELLO_FAILED = 0
+OFPET_BAD_REQUEST = 1
+OFPET_BAD_ACTION = 2
+OFPET_BAD_INSTRUCTION = 3
+OFPET_BAD_MATCH = 4
+OFPET_FLOW_MOD_FAILED = 5
+OFPET_GROUP_MOD_FAILED = 6
+OFPET_PORT_MOD_FAILED = 7
+OFPET_TABLE_MOD_FAILED = 8
+OFPET_QUEUE_OP_FAILED = 9
+OFPET_SWITCH_CONFIG_FAILED = 10
+OFPET_ROLE_REQUEST_FAILED = 11
+OFPET_METER_MOD_FAILED = 12
+OFPET_TABLE_FEATURES_FAILED = 13
+OFPET_EXPERIMENTER = 65535
+
+ofp_error_type_map = {
+    0: 'OFPET_HELLO_FAILED',
+    1: 'OFPET_BAD_REQUEST',
+    2: 'OFPET_BAD_ACTION',
+    3: 'OFPET_BAD_INSTRUCTION',
+    4: 'OFPET_BAD_MATCH',
+    5: 'OFPET_FLOW_MOD_FAILED',
+    6: 'OFPET_GROUP_MOD_FAILED',
+    7: 'OFPET_PORT_MOD_FAILED',
+    8: 'OFPET_TABLE_MOD_FAILED',
+    9: 'OFPET_QUEUE_OP_FAILED',
+    10: 'OFPET_SWITCH_CONFIG_FAILED',
+    11: 'OFPET_ROLE_REQUEST_FAILED',
+    12: 'OFPET_METER_MOD_FAILED',
+    13: 'OFPET_TABLE_FEATURES_FAILED',
+    65535: 'OFPET_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_flow_mod_command
+OFPFC_ADD = 0
+OFPFC_MODIFY = 1
+OFPFC_MODIFY_STRICT = 2
+OFPFC_DELETE = 3
+OFPFC_DELETE_STRICT = 4
+
+ofp_flow_mod_command_map = {
+    0: 'OFPFC_ADD',
+    1: 'OFPFC_MODIFY',
+    2: 'OFPFC_MODIFY_STRICT',
+    3: 'OFPFC_DELETE',
+    4: 'OFPFC_DELETE_STRICT',
+}
+
+# Identifiers from group ofp_flow_mod_failed_code
+OFPFMFC_UNKNOWN = 0
+OFPFMFC_TABLE_FULL = 1
+OFPFMFC_BAD_TABLE_ID = 2
+OFPFMFC_OVERLAP = 3
+OFPFMFC_EPERM = 4
+OFPFMFC_BAD_TIMEOUT = 5
+OFPFMFC_BAD_COMMAND = 6
+OFPFMFC_BAD_FLAGS = 7
+
+ofp_flow_mod_failed_code_map = {
+    0: 'OFPFMFC_UNKNOWN',
+    1: 'OFPFMFC_TABLE_FULL',
+    2: 'OFPFMFC_BAD_TABLE_ID',
+    3: 'OFPFMFC_OVERLAP',
+    4: 'OFPFMFC_EPERM',
+    5: 'OFPFMFC_BAD_TIMEOUT',
+    6: 'OFPFMFC_BAD_COMMAND',
+    7: 'OFPFMFC_BAD_FLAGS',
+}
+
+# Identifiers from group ofp_flow_mod_flags
+OFPFF_SEND_FLOW_REM = 1
+OFPFF_CHECK_OVERLAP = 2
+OFPFF_RESET_COUNTS = 4
+OFPFF_NO_PKT_COUNTS = 8
+OFPFF_NO_BYT_COUNTS = 16
+OFPFF_BSN_SEND_IDLE = 128
+
+ofp_flow_mod_flags_map = {
+    1: 'OFPFF_SEND_FLOW_REM',
+    2: 'OFPFF_CHECK_OVERLAP',
+    4: 'OFPFF_RESET_COUNTS',
+    8: 'OFPFF_NO_PKT_COUNTS',
+    16: 'OFPFF_NO_BYT_COUNTS',
+    128: 'OFPFF_BSN_SEND_IDLE',
+}
+
+# Identifiers from group ofp_flow_removed_reason
+OFPRR_IDLE_TIMEOUT = 0
+OFPRR_HARD_TIMEOUT = 1
+OFPRR_DELETE = 2
+OFPRR_GROUP_DELETE = 3
+
+ofp_flow_removed_reason_map = {
+    0: 'OFPRR_IDLE_TIMEOUT',
+    1: 'OFPRR_HARD_TIMEOUT',
+    2: 'OFPRR_DELETE',
+    3: 'OFPRR_GROUP_DELETE',
+}
+
+# Identifiers from group ofp_group
+OFPG_MAX = 4294967040
+OFPG_ALL = 4294967292
+OFPG_ANY = 4294967295
+
+ofp_group_map = {
+    4294967040: 'OFPG_MAX',
+    4294967292: 'OFPG_ALL',
+    4294967295: 'OFPG_ANY',
+}
+
+# Identifiers from group ofp_group_capabilities
+OFPGFC_SELECT_WEIGHT = 1
+OFPGFC_SELECT_LIVENESS = 2
+OFPGFC_CHAINING = 4
+OFPGFC_CHAINING_CHECKS = 8
+
+ofp_group_capabilities_map = {
+    1: 'OFPGFC_SELECT_WEIGHT',
+    2: 'OFPGFC_SELECT_LIVENESS',
+    4: 'OFPGFC_CHAINING',
+    8: 'OFPGFC_CHAINING_CHECKS',
+}
+
+# Identifiers from group ofp_group_mod_command
+OFPGC_ADD = 0
+OFPGC_MODIFY = 1
+OFPGC_DELETE = 2
+
+ofp_group_mod_command_map = {
+    0: 'OFPGC_ADD',
+    1: 'OFPGC_MODIFY',
+    2: 'OFPGC_DELETE',
+}
+
+# Identifiers from group ofp_group_mod_failed_code
+OFPGMFC_GROUP_EXISTS = 0
+OFPGMFC_INVALID_GROUP = 1
+OFPGMFC_WEIGHT_UNSUPPORTED = 2
+OFPGMFC_OUT_OF_GROUPS = 3
+OFPGMFC_OUT_OF_BUCKETS = 4
+OFPGMFC_CHAINING_UNSUPPORTED = 5
+OFPGMFC_WATCH_UNSUPPORTED = 6
+OFPGMFC_LOOP = 7
+OFPGMFC_UNKNOWN_GROUP = 8
+OFPGMFC_CHAINED_GROUP = 9
+OFPGMFC_BAD_TYPE = 10
+OFPGMFC_BAD_COMMAND = 11
+OFPGMFC_BAD_BUCKET = 12
+OFPGMFC_BAD_WATCH = 13
+OFPGMFC_EPERM = 14
+
+ofp_group_mod_failed_code_map = {
+    0: 'OFPGMFC_GROUP_EXISTS',
+    1: 'OFPGMFC_INVALID_GROUP',
+    2: 'OFPGMFC_WEIGHT_UNSUPPORTED',
+    3: 'OFPGMFC_OUT_OF_GROUPS',
+    4: 'OFPGMFC_OUT_OF_BUCKETS',
+    5: 'OFPGMFC_CHAINING_UNSUPPORTED',
+    6: 'OFPGMFC_WATCH_UNSUPPORTED',
+    7: 'OFPGMFC_LOOP',
+    8: 'OFPGMFC_UNKNOWN_GROUP',
+    9: 'OFPGMFC_CHAINED_GROUP',
+    10: 'OFPGMFC_BAD_TYPE',
+    11: 'OFPGMFC_BAD_COMMAND',
+    12: 'OFPGMFC_BAD_BUCKET',
+    13: 'OFPGMFC_BAD_WATCH',
+    14: 'OFPGMFC_EPERM',
+}
+
+# Identifiers from group ofp_group_type
+OFPGT_ALL = 0
+OFPGT_SELECT = 1
+OFPGT_INDIRECT = 2
+OFPGT_FF = 3
+
+ofp_group_type_map = {
+    0: 'OFPGT_ALL',
+    1: 'OFPGT_SELECT',
+    2: 'OFPGT_INDIRECT',
+    3: 'OFPGT_FF',
+}
+
+# Identifiers from group ofp_hello_elem_type
+OFPHET_VERSIONBITMAP = 1
+
+ofp_hello_elem_type_map = {
+    1: 'OFPHET_VERSIONBITMAP',
+}
+
+# Identifiers from group ofp_hello_failed_code
+OFPHFC_INCOMPATIBLE = 0
+OFPHFC_EPERM = 1
+
+ofp_hello_failed_code_map = {
+    0: 'OFPHFC_INCOMPATIBLE',
+    1: 'OFPHFC_EPERM',
+}
+
+# Identifiers from group ofp_instruction_type
+OFPIT_GOTO_TABLE = 1
+OFPIT_WRITE_METADATA = 2
+OFPIT_WRITE_ACTIONS = 3
+OFPIT_APPLY_ACTIONS = 4
+OFPIT_CLEAR_ACTIONS = 5
+OFPIT_METER = 6
+OFPIT_EXPERIMENTER = 65535
+
+ofp_instruction_type_map = {
+    1: 'OFPIT_GOTO_TABLE',
+    2: 'OFPIT_WRITE_METADATA',
+    3: 'OFPIT_WRITE_ACTIONS',
+    4: 'OFPIT_APPLY_ACTIONS',
+    5: 'OFPIT_CLEAR_ACTIONS',
+    6: 'OFPIT_METER',
+    65535: 'OFPIT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_ipv6exthdr_flags
+OFPIEH_NONEXT = 1
+OFPIEH_ESP = 2
+OFPIEH_AUTH = 4
+OFPIEH_DEST = 8
+OFPIEH_FRAG = 16
+OFPIEH_ROUTER = 32
+OFPIEH_HOP = 64
+OFPIEH_UNREP = 128
+OFPIEH_UNSEQ = 256
+
+ofp_ipv6exthdr_flags_map = {
+    1: 'OFPIEH_NONEXT',
+    2: 'OFPIEH_ESP',
+    4: 'OFPIEH_AUTH',
+    8: 'OFPIEH_DEST',
+    16: 'OFPIEH_FRAG',
+    32: 'OFPIEH_ROUTER',
+    64: 'OFPIEH_HOP',
+    128: 'OFPIEH_UNREP',
+    256: 'OFPIEH_UNSEQ',
+}
+
+# Identifiers from group ofp_match_type
+OFPMT_STANDARD = 0
+OFPMT_OXM = 1
+
+ofp_match_type_map = {
+    0: 'OFPMT_STANDARD',
+    1: 'OFPMT_OXM',
+}
+
+# Identifiers from group ofp_meter
+OFPM_MAX = 4294901760
+OFPM_SLOWPATH = 4294967293
+OFPM_CONTROLLER = 4294967294
+OFPM_ALL = 4294967295
+
+ofp_meter_map = {
+    4294901760: 'OFPM_MAX',
+    4294967293: 'OFPM_SLOWPATH',
+    4294967294: 'OFPM_CONTROLLER',
+    4294967295: 'OFPM_ALL',
+}
+
+# Identifiers from group ofp_meter_band_type
+OFPMBT_DROP = 1
+OFPMBT_DSCP_REMARK = 2
+OFPMBT_EXPERIMENTER = 65535
+
+ofp_meter_band_type_map = {
+    1: 'OFPMBT_DROP',
+    2: 'OFPMBT_DSCP_REMARK',
+    65535: 'OFPMBT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_meter_flags
+OFPMF_KBPS = 1
+OFPMF_PKTPS = 2
+OFPMF_BURST = 4
+OFPMF_STATS = 8
+
+ofp_meter_flags_map = {
+    1: 'OFPMF_KBPS',
+    2: 'OFPMF_PKTPS',
+    4: 'OFPMF_BURST',
+    8: 'OFPMF_STATS',
+}
+
+# Identifiers from group ofp_meter_mod_command
+OFPMC_ADD = 0
+OFPMC_MODIFY = 1
+OFPMC_DELETE = 2
+
+ofp_meter_mod_command_map = {
+    0: 'OFPMC_ADD',
+    1: 'OFPMC_MODIFY',
+    2: 'OFPMC_DELETE',
+}
+
+# Identifiers from group ofp_meter_mod_failed_code
+OFPMMFC_UNKNOWN = 0
+OFPMMFC_METER_EXISTS = 1
+OFPMMFC_INVALID_METER = 2
+OFPMMFC_UNKNOWN_METER = 3
+OFPMMFC_BAD_COMMAND = 4
+OFPMMFC_BAD_FLAGS = 5
+OFPMMFC_BAD_RATE = 6
+OFPMMFC_BAD_BURST = 7
+OFPMMFC_BAD_BAND = 8
+OFPMMFC_BAD_BAND_VALUE = 9
+OFPMMFC_OUT_OF_METERS = 10
+OFPMMFC_OUT_OF_BANDS = 11
+
+ofp_meter_mod_failed_code_map = {
+    0: 'OFPMMFC_UNKNOWN',
+    1: 'OFPMMFC_METER_EXISTS',
+    2: 'OFPMMFC_INVALID_METER',
+    3: 'OFPMMFC_UNKNOWN_METER',
+    4: 'OFPMMFC_BAD_COMMAND',
+    5: 'OFPMMFC_BAD_FLAGS',
+    6: 'OFPMMFC_BAD_RATE',
+    7: 'OFPMMFC_BAD_BURST',
+    8: 'OFPMMFC_BAD_BAND',
+    9: 'OFPMMFC_BAD_BAND_VALUE',
+    10: 'OFPMMFC_OUT_OF_METERS',
+    11: 'OFPMMFC_OUT_OF_BANDS',
+}
+
+# Identifiers from group ofp_oxm_class
+OFPXMC_NXM_0 = 0
+OFPXMC_NXM_1 = 1
+OFPXMC_OPENFLOW_BASIC = 32768
+OFPXMC_EXPERIMENTER = 65535
+
+ofp_oxm_class_map = {
+    0: 'OFPXMC_NXM_0',
+    1: 'OFPXMC_NXM_1',
+    32768: 'OFPXMC_OPENFLOW_BASIC',
+    65535: 'OFPXMC_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_packet_in_reason
+OFPR_NO_MATCH = 0
+OFPR_ACTION = 1
+OFPR_INVALID_TTL = 2
+OFPR_BSN_NEW_HOST = 128
+OFPR_BSN_STATION_MOVE = 129
+OFPR_BSN_BAD_VLAN = 130
+OFPR_BSN_DESTINATION_LOOKUP_FAILURE = 131
+OFPR_BSN_NO_ROUTE = 132
+OFPR_BSN_ICMP_ECHO_REQUEST = 133
+OFPR_BSN_DEST_NETWORK_UNREACHABLE = 134
+OFPR_BSN_DEST_HOST_UNREACHABLE = 135
+OFPR_BSN_DEST_PORT_UNREACHABLE = 136
+OFPR_BSN_FRAGMENTATION_REQUIRED = 137
+OFPR_BSN_ARP = 139
+OFPR_BSN_DHCP = 140
+OFPR_BSN_DEBUG = 141
+OFPR_BSN_PACKET_OF_DEATH = 142
+
+ofp_packet_in_reason_map = {
+    0: 'OFPR_NO_MATCH',
+    1: 'OFPR_ACTION',
+    2: 'OFPR_INVALID_TTL',
+    128: 'OFPR_BSN_NEW_HOST',
+    129: 'OFPR_BSN_STATION_MOVE',
+    130: 'OFPR_BSN_BAD_VLAN',
+    131: 'OFPR_BSN_DESTINATION_LOOKUP_FAILURE',
+    132: 'OFPR_BSN_NO_ROUTE',
+    133: 'OFPR_BSN_ICMP_ECHO_REQUEST',
+    134: 'OFPR_BSN_DEST_NETWORK_UNREACHABLE',
+    135: 'OFPR_BSN_DEST_HOST_UNREACHABLE',
+    136: 'OFPR_BSN_DEST_PORT_UNREACHABLE',
+    137: 'OFPR_BSN_FRAGMENTATION_REQUIRED',
+    139: 'OFPR_BSN_ARP',
+    140: 'OFPR_BSN_DHCP',
+    141: 'OFPR_BSN_DEBUG',
+    142: 'OFPR_BSN_PACKET_OF_DEATH',
+}
+
+# Identifiers from group ofp_port
+OFPP_MAX = 4294967040
+OFPP_IN_PORT = 4294967288
+OFPP_TABLE = 4294967289
+OFPP_NORMAL = 4294967290
+OFPP_FLOOD = 4294967291
+OFPP_ALL = 4294967292
+OFPP_CONTROLLER = 4294967293
+OFPP_LOCAL = 4294967294
+OFPP_ANY = 4294967295
+
+ofp_port_map = {
+    4294967040: 'OFPP_MAX',
+    4294967288: 'OFPP_IN_PORT',
+    4294967289: 'OFPP_TABLE',
+    4294967290: 'OFPP_NORMAL',
+    4294967291: 'OFPP_FLOOD',
+    4294967292: 'OFPP_ALL',
+    4294967293: 'OFPP_CONTROLLER',
+    4294967294: 'OFPP_LOCAL',
+    4294967295: 'OFPP_ANY',
+}
+
+# Identifiers from group ofp_port_config
+OFPPC_PORT_DOWN = 1
+OFPPC_NO_RECV = 4
+OFPPC_NO_FWD = 32
+OFPPC_NO_PACKET_IN = 64
+OFPPC_BSN_MIRROR_DEST = 2147483648
+
+ofp_port_config_map = {
+    1: 'OFPPC_PORT_DOWN',
+    4: 'OFPPC_NO_RECV',
+    32: 'OFPPC_NO_FWD',
+    64: 'OFPPC_NO_PACKET_IN',
+    2147483648: 'OFPPC_BSN_MIRROR_DEST',
+}
+
+# Identifiers from group ofp_port_features
+OFPPF_10MB_HD = 1
+OFPPF_10MB_FD = 2
+OFPPF_100MB_HD = 4
+OFPPF_100MB_FD = 8
+OFPPF_1GB_HD = 16
+OFPPF_1GB_FD = 32
+OFPPF_10GB_FD = 64
+OFPPF_40GB_FD = 128
+OFPPF_100GB_FD = 256
+OFPPF_1TB_FD = 512
+OFPPF_OTHER = 1024
+OFPPF_COPPER = 2048
+OFPPF_FIBER = 4096
+OFPPF_AUTONEG = 8192
+OFPPF_PAUSE = 16384
+OFPPF_PAUSE_ASYM = 32768
+OFPPF_BSN_BREAKOUT_CAPABLE = 2147483648
+
+ofp_port_features_map = {
+    1: 'OFPPF_10MB_HD',
+    2: 'OFPPF_10MB_FD',
+    4: 'OFPPF_100MB_HD',
+    8: 'OFPPF_100MB_FD',
+    16: 'OFPPF_1GB_HD',
+    32: 'OFPPF_1GB_FD',
+    64: 'OFPPF_10GB_FD',
+    128: 'OFPPF_40GB_FD',
+    256: 'OFPPF_100GB_FD',
+    512: 'OFPPF_1TB_FD',
+    1024: 'OFPPF_OTHER',
+    2048: 'OFPPF_COPPER',
+    4096: 'OFPPF_FIBER',
+    8192: 'OFPPF_AUTONEG',
+    16384: 'OFPPF_PAUSE',
+    32768: 'OFPPF_PAUSE_ASYM',
+    2147483648: 'OFPPF_BSN_BREAKOUT_CAPABLE',
+}
+
+# Identifiers from group ofp_port_mod_failed_code
+OFPPMFC_BAD_PORT = 0
+OFPPMFC_BAD_HW_ADDR = 1
+OFPPMFC_BAD_CONFIG = 2
+OFPPMFC_BAD_ADVERTISE = 3
+OFPPMFC_EPERM = 4
+
+ofp_port_mod_failed_code_map = {
+    0: 'OFPPMFC_BAD_PORT',
+    1: 'OFPPMFC_BAD_HW_ADDR',
+    2: 'OFPPMFC_BAD_CONFIG',
+    3: 'OFPPMFC_BAD_ADVERTISE',
+    4: 'OFPPMFC_EPERM',
+}
+
+# Identifiers from group ofp_port_reason
+OFPPR_ADD = 0
+OFPPR_DELETE = 1
+OFPPR_MODIFY = 2
+
+ofp_port_reason_map = {
+    0: 'OFPPR_ADD',
+    1: 'OFPPR_DELETE',
+    2: 'OFPPR_MODIFY',
+}
+
+# Identifiers from group ofp_port_state
+OFPPS_LINK_DOWN = 1
+OFPPS_BLOCKED = 2
+OFPPS_LIVE = 4
+
+ofp_port_state_map = {
+    1: 'OFPPS_LINK_DOWN',
+    2: 'OFPPS_BLOCKED',
+    4: 'OFPPS_LIVE',
+}
+
+# Identifiers from group ofp_queue_op_failed_code
+OFPQOFC_BAD_PORT = 0
+OFPQOFC_BAD_QUEUE = 1
+OFPQOFC_EPERM = 2
+
+ofp_queue_op_failed_code_map = {
+    0: 'OFPQOFC_BAD_PORT',
+    1: 'OFPQOFC_BAD_QUEUE',
+    2: 'OFPQOFC_EPERM',
+}
+
+# Identifiers from group ofp_queue_properties
+OFPQT_MIN_RATE = 1
+OFPQT_MAX_RATE = 2
+OFPQT_EXPERIMENTER = 65535
+
+ofp_queue_properties_map = {
+    1: 'OFPQT_MIN_RATE',
+    2: 'OFPQT_MAX_RATE',
+    65535: 'OFPQT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_role_request_failed_code
+OFPRRFC_STALE = 0
+OFPRRFC_UNSUP = 1
+OFPRRFC_BAD_ROLE = 2
+
+ofp_role_request_failed_code_map = {
+    0: 'OFPRRFC_STALE',
+    1: 'OFPRRFC_UNSUP',
+    2: 'OFPRRFC_BAD_ROLE',
+}
+
+# Identifiers from group ofp_stats_reply_flags
+OFPSF_REPLY_MORE = 1
+
+ofp_stats_reply_flags_map = {
+    1: 'OFPSF_REPLY_MORE',
+}
+
+# Identifiers from group ofp_stats_request_flags
+OFPSF_REQ_MORE = 1
+
+ofp_stats_request_flags_map = {
+    1: 'OFPSF_REQ_MORE',
+}
+
+# Identifiers from group ofp_stats_type
+OFPST_DESC = 0
+OFPST_FLOW = 1
+OFPST_AGGREGATE = 2
+OFPST_TABLE = 3
+OFPST_PORT = 4
+OFPST_QUEUE = 5
+OFPST_GROUP = 6
+OFPST_GROUP_DESC = 7
+OFPST_GROUP_FEATURES = 8
+OFPST_METER = 9
+OFPST_METER_CONFIG = 10
+OFPST_METER_FEATURES = 11
+OFPST_TABLE_FEATURES = 12
+OFPST_PORT_DESC = 13
+OFPST_EXPERIMENTER = 65535
+
+ofp_stats_type_map = {
+    0: 'OFPST_DESC',
+    1: 'OFPST_FLOW',
+    2: 'OFPST_AGGREGATE',
+    3: 'OFPST_TABLE',
+    4: 'OFPST_PORT',
+    5: 'OFPST_QUEUE',
+    6: 'OFPST_GROUP',
+    7: 'OFPST_GROUP_DESC',
+    8: 'OFPST_GROUP_FEATURES',
+    9: 'OFPST_METER',
+    10: 'OFPST_METER_CONFIG',
+    11: 'OFPST_METER_FEATURES',
+    12: 'OFPST_TABLE_FEATURES',
+    13: 'OFPST_PORT_DESC',
+    65535: 'OFPST_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_switch_config_failed_code
+OFPSCFC_BAD_FLAGS = 0
+OFPSCFC_BAD_LEN = 1
+OFPSCFC_EPERM = 2
+
+ofp_switch_config_failed_code_map = {
+    0: 'OFPSCFC_BAD_FLAGS',
+    1: 'OFPSCFC_BAD_LEN',
+    2: 'OFPSCFC_EPERM',
+}
+
+# Identifiers from group ofp_table
+OFPTT_MAX = 254
+OFPTT_ALL = 255
+
+ofp_table_map = {
+    254: 'OFPTT_MAX',
+    255: 'OFPTT_ALL',
+}
+
+# Identifiers from group ofp_table_config
+OFPTC_DEPRECATED_MASK = 3
+
+ofp_table_config_map = {
+    3: 'OFPTC_DEPRECATED_MASK',
+}
+
+# Identifiers from group ofp_table_feature_prop_type
+OFPTFPT_INSTRUCTIONS = 0
+OFPTFPT_INSTRUCTIONS_MISS = 1
+OFPTFPT_NEXT_TABLES = 2
+OFPTFPT_NEXT_TABLES_MISS = 3
+OFPTFPT_WRITE_ACTIONS = 4
+OFPTFPT_WRITE_ACTIONS_MISS = 5
+OFPTFPT_APPLY_ACTIONS = 6
+OFPTFPT_APPLY_ACTIONS_MISS = 7
+OFPTFPT_MATCH = 8
+OFPTFPT_WILDCARDS = 10
+OFPTFPT_WRITE_SETFIELD = 12
+OFPTFPT_WRITE_SETFIELD_MISS = 13
+OFPTFPT_APPLY_SETFIELD = 14
+OFPTFPT_APPLY_SETFIELD_MISS = 15
+OFPTFPT_EXPERIMENTER = 65534
+OFPTFPT_EXPERIMENTER_MISS = 65535
+
+ofp_table_feature_prop_type_map = {
+    0: 'OFPTFPT_INSTRUCTIONS',
+    1: 'OFPTFPT_INSTRUCTIONS_MISS',
+    2: 'OFPTFPT_NEXT_TABLES',
+    3: 'OFPTFPT_NEXT_TABLES_MISS',
+    4: 'OFPTFPT_WRITE_ACTIONS',
+    5: 'OFPTFPT_WRITE_ACTIONS_MISS',
+    6: 'OFPTFPT_APPLY_ACTIONS',
+    7: 'OFPTFPT_APPLY_ACTIONS_MISS',
+    8: 'OFPTFPT_MATCH',
+    10: 'OFPTFPT_WILDCARDS',
+    12: 'OFPTFPT_WRITE_SETFIELD',
+    13: 'OFPTFPT_WRITE_SETFIELD_MISS',
+    14: 'OFPTFPT_APPLY_SETFIELD',
+    15: 'OFPTFPT_APPLY_SETFIELD_MISS',
+    65534: 'OFPTFPT_EXPERIMENTER',
+    65535: 'OFPTFPT_EXPERIMENTER_MISS',
+}
+
+# Identifiers from group ofp_table_features_failed_code
+OFPTFFC_BAD_TABLE = 0
+OFPTFFC_BAD_METADATA = 1
+OFPTFFC_BAD_TYPE = 2
+OFPTFFC_BAD_LEN = 3
+OFPTFFC_BAD_ARGUMENT = 4
+OFPTFFC_EPERM = 5
+
+ofp_table_features_failed_code_map = {
+    0: 'OFPTFFC_BAD_TABLE',
+    1: 'OFPTFFC_BAD_METADATA',
+    2: 'OFPTFFC_BAD_TYPE',
+    3: 'OFPTFFC_BAD_LEN',
+    4: 'OFPTFFC_BAD_ARGUMENT',
+    5: 'OFPTFFC_EPERM',
+}
+
+# Identifiers from group ofp_table_mod_failed_code
+OFPTMFC_BAD_TABLE = 0
+OFPTMFC_BAD_CONFIG = 1
+OFPTMFC_EPERM = 2
+
+ofp_table_mod_failed_code_map = {
+    0: 'OFPTMFC_BAD_TABLE',
+    1: 'OFPTMFC_BAD_CONFIG',
+    2: 'OFPTMFC_EPERM',
+}
+
+# Identifiers from group ofp_type
+OFPT_HELLO = 0
+OFPT_ERROR = 1
+OFPT_ECHO_REQUEST = 2
+OFPT_ECHO_REPLY = 3
+OFPT_EXPERIMENTER = 4
+OFPT_FEATURES_REQUEST = 5
+OFPT_FEATURES_REPLY = 6
+OFPT_GET_CONFIG_REQUEST = 7
+OFPT_GET_CONFIG_REPLY = 8
+OFPT_SET_CONFIG = 9
+OFPT_PACKET_IN = 10
+OFPT_FLOW_REMOVED = 11
+OFPT_PORT_STATUS = 12
+OFPT_PACKET_OUT = 13
+OFPT_FLOW_MOD = 14
+OFPT_GROUP_MOD = 15
+OFPT_PORT_MOD = 16
+OFPT_TABLE_MOD = 17
+OFPT_STATS_REQUEST = 18
+OFPT_STATS_REPLY = 19
+OFPT_BARRIER_REQUEST = 20
+OFPT_BARRIER_REPLY = 21
+OFPT_QUEUE_GET_CONFIG_REQUEST = 22
+OFPT_QUEUE_GET_CONFIG_REPLY = 23
+OFPT_ROLE_REQUEST = 24
+OFPT_ROLE_REPLY = 25
+OFPT_GET_ASYNC_REQUEST = 26
+OFPT_GET_ASYNC_REPLY = 27
+OFPT_SET_ASYNC = 28
+OFPT_METER_MOD = 29
+
+ofp_type_map = {
+    0: 'OFPT_HELLO',
+    1: 'OFPT_ERROR',
+    2: 'OFPT_ECHO_REQUEST',
+    3: 'OFPT_ECHO_REPLY',
+    4: 'OFPT_EXPERIMENTER',
+    5: 'OFPT_FEATURES_REQUEST',
+    6: 'OFPT_FEATURES_REPLY',
+    7: 'OFPT_GET_CONFIG_REQUEST',
+    8: 'OFPT_GET_CONFIG_REPLY',
+    9: 'OFPT_SET_CONFIG',
+    10: 'OFPT_PACKET_IN',
+    11: 'OFPT_FLOW_REMOVED',
+    12: 'OFPT_PORT_STATUS',
+    13: 'OFPT_PACKET_OUT',
+    14: 'OFPT_FLOW_MOD',
+    15: 'OFPT_GROUP_MOD',
+    16: 'OFPT_PORT_MOD',
+    17: 'OFPT_TABLE_MOD',
+    18: 'OFPT_STATS_REQUEST',
+    19: 'OFPT_STATS_REPLY',
+    20: 'OFPT_BARRIER_REQUEST',
+    21: 'OFPT_BARRIER_REPLY',
+    22: 'OFPT_QUEUE_GET_CONFIG_REQUEST',
+    23: 'OFPT_QUEUE_GET_CONFIG_REPLY',
+    24: 'OFPT_ROLE_REQUEST',
+    25: 'OFPT_ROLE_REPLY',
+    26: 'OFPT_GET_ASYNC_REQUEST',
+    27: 'OFPT_GET_ASYNC_REPLY',
+    28: 'OFPT_SET_ASYNC',
+    29: 'OFPT_METER_MOD',
+}
+
+# Identifiers from group ofp_vlan_id
+OFPVID_NONE = 0
+OFPVID_PRESENT = 4096
+
+ofp_vlan_id_map = {
+    0: 'OFPVID_NONE',
+    4096: 'OFPVID_PRESENT',
+}
+
diff --git a/Fabric/Utilities/src/python/loxi/of13/instruction.py b/Fabric/Utilities/src/python/loxi/of13/instruction.py
new file mode 100644
index 0000000..7bf9b62
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/instruction.py
@@ -0,0 +1,1171 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class instruction(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = instruction.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = instruction()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("instruction {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class apply_actions(instruction):
+    type = 4
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[4] = apply_actions
+
+class experimenter(instruction):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_arp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_arp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_arp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_arp_offload
+
+class bsn_auto_negotiation(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_auto_negotiation()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_auto_negotiation {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[11] = bsn_auto_negotiation
+
+class bsn_deny(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_deny()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_deny {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_deny
+
+class bsn_dhcp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_dhcp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_dhcp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_dhcp_offload
+
+class bsn_disable_l3(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_l3()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_l3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[13] = bsn_disable_l3
+
+class bsn_disable_split_horizon_check(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_split_horizon_check()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_split_horizon_check {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[3] = bsn_disable_split_horizon_check
+
+class bsn_disable_src_mac_check(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 0
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_src_mac_check()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 0)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_src_mac_check {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[0] = bsn_disable_src_mac_check
+
+class bsn_disable_vlan_counters(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_vlan_counters()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_vlan_counters {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[9] = bsn_disable_vlan_counters
+
+class bsn_internal_priority(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_internal_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_internal_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[12] = bsn_internal_priority
+
+class bsn_packet_of_death(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_packet_of_death()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_packet_of_death {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[6] = bsn_packet_of_death
+
+class bsn_permit(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_permit()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_permit {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_permit
+
+class bsn_prioritize_pdus(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_prioritize_pdus()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_prioritize_pdus {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[7] = bsn_prioritize_pdus
+
+class bsn_require_vlan_xlate(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_require_vlan_xlate()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_require_vlan_xlate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[8] = bsn_require_vlan_xlate
+
+class bsn_span_destination(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_span_destination()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_span_destination {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[10] = bsn_span_destination
+
+class clear_actions(instruction):
+    type = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = clear_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("clear_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[5] = clear_actions
+
+class goto_table(instruction):
+    type = 1
+
+    def __init__(self, table_id=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = goto_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("goto_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[1] = goto_table
+
+class meter(instruction):
+    type = 6
+
+    def __init__(self, meter_id=None):
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.meter_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.meter_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.meter_id != other.meter_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[6] = meter
+
+class write_actions(instruction):
+    type = 3
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[3] = write_actions
+
+class write_metadata(instruction):
+    type = 2
+
+    def __init__(self, metadata=None, metadata_mask=None):
+        if metadata != None:
+            self.metadata = metadata
+        else:
+            self.metadata = 0
+        if metadata_mask != None:
+            self.metadata_mask = metadata_mask
+        else:
+            self.metadata_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.metadata))
+        packed.append(struct.pack("!Q", self.metadata_mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_metadata()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.metadata = reader.read("!Q")[0]
+        obj.metadata_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.metadata != other.metadata: return False
+        if self.metadata_mask != other.metadata_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("metadata = ");
+                q.text("%#x" % self.metadata)
+                q.text(","); q.breakable()
+                q.text("metadata_mask = ");
+                q.text("%#x" % self.metadata_mask)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[2] = write_metadata
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of13/instruction_id.py b/Fabric/Utilities/src/python/loxi/of13/instruction_id.py
new file mode 100644
index 0000000..67b6506
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/instruction_id.py
@@ -0,0 +1,1060 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class instruction_id(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = instruction_id.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = instruction_id()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("instruction_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class apply_actions(instruction_id):
+    type = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[4] = apply_actions
+
+class experimenter(instruction_id):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_arp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_arp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_arp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_arp_offload
+
+class bsn_auto_negotiation(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_auto_negotiation()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_auto_negotiation {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[11] = bsn_auto_negotiation
+
+class bsn_deny(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_deny()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_deny {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_deny
+
+class bsn_dhcp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_dhcp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_dhcp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_dhcp_offload
+
+class bsn_disable_l3(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_l3()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_l3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[13] = bsn_disable_l3
+
+class bsn_disable_split_horizon_check(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_split_horizon_check()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_split_horizon_check {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[3] = bsn_disable_split_horizon_check
+
+class bsn_disable_src_mac_check(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 0
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_src_mac_check()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 0)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_src_mac_check {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[0] = bsn_disable_src_mac_check
+
+class bsn_disable_vlan_counters(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_vlan_counters()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_vlan_counters {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[9] = bsn_disable_vlan_counters
+
+class bsn_internal_priority(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_internal_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_internal_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[12] = bsn_internal_priority
+
+class bsn_packet_of_death(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_packet_of_death()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_packet_of_death {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[6] = bsn_packet_of_death
+
+class bsn_permit(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_permit()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_permit {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_permit
+
+class bsn_prioritize_pdus(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_prioritize_pdus()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_prioritize_pdus {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[7] = bsn_prioritize_pdus
+
+class bsn_require_vlan_xlate(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_require_vlan_xlate()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_require_vlan_xlate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[8] = bsn_require_vlan_xlate
+
+class bsn_span_destination(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_span_destination()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_span_destination {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[10] = bsn_span_destination
+
+class clear_actions(instruction_id):
+    type = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = clear_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("clear_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[5] = clear_actions
+
+class goto_table(instruction_id):
+    type = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = goto_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("goto_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[1] = goto_table
+
+class meter(instruction_id):
+    type = 6
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[6] = meter
+
+class write_actions(instruction_id):
+    type = 3
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[3] = write_actions
+
+class write_metadata(instruction_id):
+    type = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_metadata()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[2] = write_metadata
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of13/message.py b/Fabric/Utilities/src/python/loxi/of13/message.py
new file mode 100644
index 0000000..c9f27e6
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/message.py
@@ -0,0 +1,15224 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class message(loxi.OFObject):
+    subtypes = {}
+
+    version = 4
+
+    def __init__(self, type=None, xid=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 1)
+        subclass = message.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = message()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        obj.type = reader.read("!B")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("message {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+
+class stats_reply(message):
+    subtypes = {}
+
+    version = 4
+    type = 19
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[19] = stats_reply
+
+class aggregate_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, packet_count=None, byte_count=None, flow_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if flow_count != None:
+            self.flow_count = flow_count
+        else:
+            self.flow_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(struct.pack("!L", self.flow_count))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.flow_count = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.flow_count != other.flow_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("flow_count = ");
+                q.text("%#x" % self.flow_count)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[2] = aggregate_stats_reply
+
+class stats_request(message):
+    subtypes = {}
+
+    version = 4
+    type = 18
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[18] = stats_request
+
+class aggregate_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[2] = aggregate_stats_request
+
+class async_get_reply(message):
+    version = 4
+    type = 27
+
+    def __init__(self, xid=None, packet_in_mask_equal_master=None, packet_in_mask_slave=None, port_status_mask_equal_master=None, port_status_mask_slave=None, flow_removed_mask_equal_master=None, flow_removed_mask_slave=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if packet_in_mask_equal_master != None:
+            self.packet_in_mask_equal_master = packet_in_mask_equal_master
+        else:
+            self.packet_in_mask_equal_master = 0
+        if packet_in_mask_slave != None:
+            self.packet_in_mask_slave = packet_in_mask_slave
+        else:
+            self.packet_in_mask_slave = 0
+        if port_status_mask_equal_master != None:
+            self.port_status_mask_equal_master = port_status_mask_equal_master
+        else:
+            self.port_status_mask_equal_master = 0
+        if port_status_mask_slave != None:
+            self.port_status_mask_slave = port_status_mask_slave
+        else:
+            self.port_status_mask_slave = 0
+        if flow_removed_mask_equal_master != None:
+            self.flow_removed_mask_equal_master = flow_removed_mask_equal_master
+        else:
+            self.flow_removed_mask_equal_master = 0
+        if flow_removed_mask_slave != None:
+            self.flow_removed_mask_slave = flow_removed_mask_slave
+        else:
+            self.flow_removed_mask_slave = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.packet_in_mask_equal_master))
+        packed.append(struct.pack("!L", self.packet_in_mask_slave))
+        packed.append(struct.pack("!L", self.port_status_mask_equal_master))
+        packed.append(struct.pack("!L", self.port_status_mask_slave))
+        packed.append(struct.pack("!L", self.flow_removed_mask_equal_master))
+        packed.append(struct.pack("!L", self.flow_removed_mask_slave))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = async_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 27)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.packet_in_mask_equal_master = reader.read("!L")[0]
+        obj.packet_in_mask_slave = reader.read("!L")[0]
+        obj.port_status_mask_equal_master = reader.read("!L")[0]
+        obj.port_status_mask_slave = reader.read("!L")[0]
+        obj.flow_removed_mask_equal_master = reader.read("!L")[0]
+        obj.flow_removed_mask_slave = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.packet_in_mask_equal_master != other.packet_in_mask_equal_master: return False
+        if self.packet_in_mask_slave != other.packet_in_mask_slave: return False
+        if self.port_status_mask_equal_master != other.port_status_mask_equal_master: return False
+        if self.port_status_mask_slave != other.port_status_mask_slave: return False
+        if self.flow_removed_mask_equal_master != other.flow_removed_mask_equal_master: return False
+        if self.flow_removed_mask_slave != other.flow_removed_mask_slave: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("packet_in_mask_equal_master = ");
+                q.text("%#x" % self.packet_in_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("packet_in_mask_slave = ");
+                q.text("%#x" % self.packet_in_mask_slave)
+                q.text(","); q.breakable()
+                q.text("port_status_mask_equal_master = ");
+                q.text("%#x" % self.port_status_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("port_status_mask_slave = ");
+                q.text("%#x" % self.port_status_mask_slave)
+                q.text(","); q.breakable()
+                q.text("flow_removed_mask_equal_master = ");
+                q.text("%#x" % self.flow_removed_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("flow_removed_mask_slave = ");
+                q.text("%#x" % self.flow_removed_mask_slave)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[27] = async_get_reply
+
+class async_get_request(message):
+    version = 4
+    type = 26
+
+    def __init__(self, xid=None, packet_in_mask_equal_master=None, packet_in_mask_slave=None, port_status_mask_equal_master=None, port_status_mask_slave=None, flow_removed_mask_equal_master=None, flow_removed_mask_slave=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if packet_in_mask_equal_master != None:
+            self.packet_in_mask_equal_master = packet_in_mask_equal_master
+        else:
+            self.packet_in_mask_equal_master = 0
+        if packet_in_mask_slave != None:
+            self.packet_in_mask_slave = packet_in_mask_slave
+        else:
+            self.packet_in_mask_slave = 0
+        if port_status_mask_equal_master != None:
+            self.port_status_mask_equal_master = port_status_mask_equal_master
+        else:
+            self.port_status_mask_equal_master = 0
+        if port_status_mask_slave != None:
+            self.port_status_mask_slave = port_status_mask_slave
+        else:
+            self.port_status_mask_slave = 0
+        if flow_removed_mask_equal_master != None:
+            self.flow_removed_mask_equal_master = flow_removed_mask_equal_master
+        else:
+            self.flow_removed_mask_equal_master = 0
+        if flow_removed_mask_slave != None:
+            self.flow_removed_mask_slave = flow_removed_mask_slave
+        else:
+            self.flow_removed_mask_slave = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.packet_in_mask_equal_master))
+        packed.append(struct.pack("!L", self.packet_in_mask_slave))
+        packed.append(struct.pack("!L", self.port_status_mask_equal_master))
+        packed.append(struct.pack("!L", self.port_status_mask_slave))
+        packed.append(struct.pack("!L", self.flow_removed_mask_equal_master))
+        packed.append(struct.pack("!L", self.flow_removed_mask_slave))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = async_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 26)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.packet_in_mask_equal_master = reader.read("!L")[0]
+        obj.packet_in_mask_slave = reader.read("!L")[0]
+        obj.port_status_mask_equal_master = reader.read("!L")[0]
+        obj.port_status_mask_slave = reader.read("!L")[0]
+        obj.flow_removed_mask_equal_master = reader.read("!L")[0]
+        obj.flow_removed_mask_slave = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.packet_in_mask_equal_master != other.packet_in_mask_equal_master: return False
+        if self.packet_in_mask_slave != other.packet_in_mask_slave: return False
+        if self.port_status_mask_equal_master != other.port_status_mask_equal_master: return False
+        if self.port_status_mask_slave != other.port_status_mask_slave: return False
+        if self.flow_removed_mask_equal_master != other.flow_removed_mask_equal_master: return False
+        if self.flow_removed_mask_slave != other.flow_removed_mask_slave: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("packet_in_mask_equal_master = ");
+                q.text("%#x" % self.packet_in_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("packet_in_mask_slave = ");
+                q.text("%#x" % self.packet_in_mask_slave)
+                q.text(","); q.breakable()
+                q.text("port_status_mask_equal_master = ");
+                q.text("%#x" % self.port_status_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("port_status_mask_slave = ");
+                q.text("%#x" % self.port_status_mask_slave)
+                q.text(","); q.breakable()
+                q.text("flow_removed_mask_equal_master = ");
+                q.text("%#x" % self.flow_removed_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("flow_removed_mask_slave = ");
+                q.text("%#x" % self.flow_removed_mask_slave)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[26] = async_get_request
+
+class async_set(message):
+    version = 4
+    type = 28
+
+    def __init__(self, xid=None, packet_in_mask_equal_master=None, packet_in_mask_slave=None, port_status_mask_equal_master=None, port_status_mask_slave=None, flow_removed_mask_equal_master=None, flow_removed_mask_slave=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if packet_in_mask_equal_master != None:
+            self.packet_in_mask_equal_master = packet_in_mask_equal_master
+        else:
+            self.packet_in_mask_equal_master = 0
+        if packet_in_mask_slave != None:
+            self.packet_in_mask_slave = packet_in_mask_slave
+        else:
+            self.packet_in_mask_slave = 0
+        if port_status_mask_equal_master != None:
+            self.port_status_mask_equal_master = port_status_mask_equal_master
+        else:
+            self.port_status_mask_equal_master = 0
+        if port_status_mask_slave != None:
+            self.port_status_mask_slave = port_status_mask_slave
+        else:
+            self.port_status_mask_slave = 0
+        if flow_removed_mask_equal_master != None:
+            self.flow_removed_mask_equal_master = flow_removed_mask_equal_master
+        else:
+            self.flow_removed_mask_equal_master = 0
+        if flow_removed_mask_slave != None:
+            self.flow_removed_mask_slave = flow_removed_mask_slave
+        else:
+            self.flow_removed_mask_slave = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.packet_in_mask_equal_master))
+        packed.append(struct.pack("!L", self.packet_in_mask_slave))
+        packed.append(struct.pack("!L", self.port_status_mask_equal_master))
+        packed.append(struct.pack("!L", self.port_status_mask_slave))
+        packed.append(struct.pack("!L", self.flow_removed_mask_equal_master))
+        packed.append(struct.pack("!L", self.flow_removed_mask_slave))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = async_set()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 28)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.packet_in_mask_equal_master = reader.read("!L")[0]
+        obj.packet_in_mask_slave = reader.read("!L")[0]
+        obj.port_status_mask_equal_master = reader.read("!L")[0]
+        obj.port_status_mask_slave = reader.read("!L")[0]
+        obj.flow_removed_mask_equal_master = reader.read("!L")[0]
+        obj.flow_removed_mask_slave = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.packet_in_mask_equal_master != other.packet_in_mask_equal_master: return False
+        if self.packet_in_mask_slave != other.packet_in_mask_slave: return False
+        if self.port_status_mask_equal_master != other.port_status_mask_equal_master: return False
+        if self.port_status_mask_slave != other.port_status_mask_slave: return False
+        if self.flow_removed_mask_equal_master != other.flow_removed_mask_equal_master: return False
+        if self.flow_removed_mask_slave != other.flow_removed_mask_slave: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_set {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("packet_in_mask_equal_master = ");
+                q.text("%#x" % self.packet_in_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("packet_in_mask_slave = ");
+                q.text("%#x" % self.packet_in_mask_slave)
+                q.text(","); q.breakable()
+                q.text("port_status_mask_equal_master = ");
+                q.text("%#x" % self.port_status_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("port_status_mask_slave = ");
+                q.text("%#x" % self.port_status_mask_slave)
+                q.text(","); q.breakable()
+                q.text("flow_removed_mask_equal_master = ");
+                q.text("%#x" % self.flow_removed_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("flow_removed_mask_slave = ");
+                q.text("%#x" % self.flow_removed_mask_slave)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[28] = async_set
+
+class error_msg(message):
+    subtypes = {}
+
+    version = 4
+    type = 1
+
+    def __init__(self, xid=None, err_type=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if err_type != None:
+            self.err_type = err_type
+        else:
+            self.err_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = error_msg.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.err_type = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.err_type != other.err_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[1] = error_msg
+
+class bad_action_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 2
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_action_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 2)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_action_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[2] = bad_action_error_msg
+
+class bad_instruction_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 3
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_instruction_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 3)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_instruction_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[3] = bad_instruction_error_msg
+
+class bad_match_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 4
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_match_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 4)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_match_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[4] = bad_match_error_msg
+
+class bad_request_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 1
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_request_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 1)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_request_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[1] = bad_request_error_msg
+
+class barrier_reply(message):
+    version = 4
+    type = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 21)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[21] = barrier_reply
+
+class barrier_request(message):
+    version = 4
+    type = 20
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 20)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[20] = barrier_request
+
+class experimenter(message):
+    subtypes = {}
+
+    version = 4
+    type = 4
+
+    def __init__(self, xid=None, experimenter=None, subtype=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[4] = experimenter
+
+class bsn_header(experimenter):
+    subtypes = {}
+
+    version = 4
+    type = 4
+    experimenter = 6035143
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = bsn_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn_header
+
+class bsn_arp_idle(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 60
+
+    def __init__(self, xid=None, vlan_vid=None, ipv4_addr=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        if ipv4_addr != None:
+            self.ipv4_addr = ipv4_addr
+        else:
+            self.ipv4_addr = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.ipv4_addr))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_arp_idle()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 60)
+        obj.vlan_vid = reader.read("!H")[0]
+        reader.skip(2)
+        obj.ipv4_addr = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vlan_vid != other.vlan_vid: return False
+        if self.ipv4_addr != other.ipv4_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_arp_idle {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+                q.text(","); q.breakable()
+                q.text("ipv4_addr = ");
+                q.text(util.pretty_ipv4(self.ipv4_addr))
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[60] = bsn_arp_idle
+
+class bsn_bw_clear_data_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 22
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 22)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[22] = bsn_bw_clear_data_reply
+
+class bsn_bw_clear_data_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 21)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[21] = bsn_bw_clear_data_request
+
+class bsn_bw_enable_get_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 20
+
+    def __init__(self, xid=None, enabled=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enabled))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 20)
+        obj.enabled = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[20] = bsn_bw_enable_get_reply
+
+class bsn_bw_enable_get_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 19
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 19)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[19] = bsn_bw_enable_get_request
+
+class bsn_bw_enable_set_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 23
+
+    def __init__(self, xid=None, enable=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 23)
+        obj.enable = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[23] = bsn_bw_enable_set_reply
+
+class bsn_bw_enable_set_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 18
+
+    def __init__(self, xid=None, enable=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 18)
+        obj.enable = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[18] = bsn_bw_enable_set_request
+
+class bsn_controller_connections_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 57
+
+    def __init__(self, xid=None, connections=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if connections != None:
+            self.connections = connections
+        else:
+            self.connections = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.connections))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_controller_connections_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 57)
+        obj.connections = loxi.generic_util.unpack_list(reader, ofp.common.bsn_controller_connection.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.connections != other.connections: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_controller_connections_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("connections = ");
+                q.pp(self.connections)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[57] = bsn_controller_connections_reply
+
+class bsn_controller_connections_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 56
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_controller_connections_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 56)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_controller_connections_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[56] = bsn_controller_connections_request
+
+class experimenter_stats_reply(stats_reply):
+    subtypes = {}
+
+    version = 4
+    type = 19
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[65535] = experimenter_stats_reply
+
+class bsn_stats_reply(experimenter_stats_reply):
+    subtypes = {}
+
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_reply.subtypes[6035143] = bsn_stats_reply
+
+class bsn_debug_counter_desc_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_debug_counter_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[13] = bsn_debug_counter_desc_stats_reply
+
+class experimenter_stats_request(stats_request):
+    subtypes = {}
+
+    version = 4
+    type = 18
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[65535] = experimenter_stats_request
+
+class bsn_stats_request(experimenter_stats_request):
+    subtypes = {}
+
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_request.subtypes[6035143] = bsn_stats_request
+
+class bsn_debug_counter_desc_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[13] = bsn_debug_counter_desc_stats_request
+
+class bsn_debug_counter_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_debug_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[12] = bsn_debug_counter_stats_reply
+
+class bsn_debug_counter_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[12] = bsn_debug_counter_stats_request
+
+class bsn_flow_checksum_bucket_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_checksum_bucket_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_flow_checksum_bucket_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_checksum_bucket_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[10] = bsn_flow_checksum_bucket_stats_reply
+
+class bsn_flow_checksum_bucket_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, flags=None, table_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.table_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_checksum_bucket_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.table_id = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_checksum_bucket_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[10] = bsn_flow_checksum_bucket_stats_request
+
+class bsn_flow_idle(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 40
+
+    def __init__(self, xid=None, cookie=None, priority=None, table_id=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 5)
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 40)
+        obj.cookie = reader.read("!Q")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(5)
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.priority != other.priority: return False
+        if self.table_id != other.table_id: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[40] = bsn_flow_idle
+
+class bsn_flow_idle_enable_get_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 39
+
+    def __init__(self, xid=None, enabled=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enabled))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 39)
+        obj.enabled = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[39] = bsn_flow_idle_enable_get_reply
+
+class bsn_flow_idle_enable_get_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 38
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 38)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[38] = bsn_flow_idle_enable_get_request
+
+class bsn_flow_idle_enable_set_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 37
+
+    def __init__(self, xid=None, enable=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_set_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 37)
+        obj.enable = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_set_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[37] = bsn_flow_idle_enable_set_reply
+
+class bsn_flow_idle_enable_set_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 36
+
+    def __init__(self, xid=None, enable=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_set_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 36)
+        obj.enable = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_set_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[36] = bsn_flow_idle_enable_set_request
+
+class bsn_generic_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generic_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_generic_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generic_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[16] = bsn_generic_stats_reply
+
+class bsn_generic_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, flags=None, name=None, tlvs=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if tlvs != None:
+            self.tlvs = tlvs
+        else:
+            self.tlvs = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!64s", self.name))
+        packed.append(loxi.generic_util.pack_list(self.tlvs))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generic_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.name = reader.read("!64s")[0].rstrip("\x00")
+        obj.tlvs = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.name != other.name: return False
+        if self.tlvs != other.tlvs: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generic_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("tlvs = ");
+                q.pp(self.tlvs)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[16] = bsn_generic_stats_request
+
+class bsn_gentable_bucket_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_bucket_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_bucket_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_bucket_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[5] = bsn_gentable_bucket_stats_reply
+
+class bsn_gentable_bucket_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, flags=None, table_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_bucket_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.table_id = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_bucket_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[5] = bsn_gentable_bucket_stats_request
+
+class bsn_gentable_clear_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 49
+
+    def __init__(self, xid=None, table_id=None, deleted_count=None, error_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if deleted_count != None:
+            self.deleted_count = deleted_count
+        else:
+            self.deleted_count = 0
+        if error_count != None:
+            self.error_count = error_count
+        else:
+            self.error_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.deleted_count))
+        packed.append(struct.pack("!L", self.error_count))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_clear_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 49)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.deleted_count = reader.read("!L")[0]
+        obj.error_count = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.deleted_count != other.deleted_count: return False
+        if self.error_count != other.error_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_clear_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("deleted_count = ");
+                q.text("%#x" % self.deleted_count)
+                q.text(","); q.breakable()
+                q.text("error_count = ");
+                q.text("%#x" % self.error_count)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[49] = bsn_gentable_clear_reply
+
+class bsn_gentable_clear_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 48
+
+    def __init__(self, xid=None, table_id=None, checksum=None, checksum_mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if checksum_mask != None:
+            self.checksum_mask = checksum_mask
+        else:
+            self.checksum_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(util.pack_checksum_128(self.checksum_mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_clear_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 48)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.checksum_mask = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.checksum_mask != other.checksum_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_clear_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("checksum_mask = ");
+                q.pp(self.checksum_mask)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[48] = bsn_gentable_clear_request
+
+class bsn_gentable_desc_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[4] = bsn_gentable_desc_stats_reply
+
+class bsn_gentable_desc_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[4] = bsn_gentable_desc_stats_request
+
+class bsn_gentable_entry_add(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 46
+
+    def __init__(self, xid=None, table_id=None, checksum=None, key=None, value=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        if value != None:
+            self.value = value
+        else:
+            self.value = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(struct.pack("!H", 0)) # placeholder for key_length at index 7
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        packed[7] = struct.pack("!H", len(packed[-1]))
+        packed.append(loxi.generic_util.pack_list(self.value))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 46)
+        obj.table_id = reader.read("!H")[0]
+        _key_length = reader.read("!H")[0]
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.key = loxi.generic_util.unpack_list(reader.slice(_key_length), ofp.bsn_tlv.bsn_tlv.unpack)
+        obj.value = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.key != other.key: return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+                q.text(","); q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[46] = bsn_gentable_entry_add
+
+class bsn_gentable_entry_delete(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 47
+
+    def __init__(self, xid=None, table_id=None, key=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 47)
+        obj.table_id = reader.read("!H")[0]
+        obj.key = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.key != other.key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[47] = bsn_gentable_entry_delete
+
+class bsn_gentable_entry_desc_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_entry_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[2] = bsn_gentable_entry_desc_stats_reply
+
+class bsn_gentable_entry_desc_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, xid=None, flags=None, table_id=None, checksum=None, checksum_mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if checksum_mask != None:
+            self.checksum_mask = checksum_mask
+        else:
+            self.checksum_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(util.pack_checksum_128(self.checksum_mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.checksum_mask = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.checksum_mask != other.checksum_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("checksum_mask = ");
+                q.pp(self.checksum_mask)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[2] = bsn_gentable_entry_desc_stats_request
+
+class bsn_gentable_entry_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_entry_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[3] = bsn_gentable_entry_stats_reply
+
+class bsn_gentable_entry_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, flags=None, table_id=None, checksum=None, checksum_mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if checksum_mask != None:
+            self.checksum_mask = checksum_mask
+        else:
+            self.checksum_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(util.pack_checksum_128(self.checksum_mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.checksum_mask = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.checksum_mask != other.checksum_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("checksum_mask = ");
+                q.pp(self.checksum_mask)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[3] = bsn_gentable_entry_stats_request
+
+class bsn_gentable_set_buckets_size(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 50
+
+    def __init__(self, xid=None, table_id=None, buckets_size=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if buckets_size != None:
+            self.buckets_size = buckets_size
+        else:
+            self.buckets_size = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.buckets_size))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_set_buckets_size()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 50)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.buckets_size = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.buckets_size != other.buckets_size: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_set_buckets_size {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("buckets_size = ");
+                q.text("%#x" % self.buckets_size)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[50] = bsn_gentable_set_buckets_size
+
+class bsn_gentable_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[7] = bsn_gentable_stats_reply
+
+class bsn_gentable_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[7] = bsn_gentable_stats_request
+
+class bsn_get_interfaces_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, interfaces=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if interfaces != None:
+            self.interfaces = interfaces
+        else:
+            self.interfaces = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.interfaces))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.interfaces = loxi.generic_util.unpack_list(reader, ofp.common.bsn_interface.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.interfaces != other.interfaces: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("interfaces = ");
+                q.pp(self.interfaces)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[10] = bsn_get_interfaces_reply
+
+class bsn_get_interfaces_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[9] = bsn_get_interfaces_request
+
+class bsn_get_mirroring_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[5] = bsn_get_mirroring_reply
+
+class bsn_get_mirroring_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[4] = bsn_get_mirroring_request
+
+class bsn_get_switch_pipeline_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 52
+
+    def __init__(self, xid=None, pipeline=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if pipeline != None:
+            self.pipeline = pipeline
+        else:
+            self.pipeline = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!256s", self.pipeline))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_switch_pipeline_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 52)
+        obj.pipeline = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.pipeline != other.pipeline: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_switch_pipeline_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("pipeline = ");
+                q.pp(self.pipeline)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[52] = bsn_get_switch_pipeline_reply
+
+class bsn_get_switch_pipeline_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 51
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_switch_pipeline_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 51)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_switch_pipeline_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[51] = bsn_get_switch_pipeline_request
+
+class bsn_image_desc_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 14
+
+    def __init__(self, xid=None, flags=None, image_checksum=None, startup_config_checksum=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if image_checksum != None:
+            self.image_checksum = image_checksum
+        else:
+            self.image_checksum = ""
+        if startup_config_checksum != None:
+            self.startup_config_checksum = startup_config_checksum
+        else:
+            self.startup_config_checksum = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!256s", self.image_checksum))
+        packed.append(struct.pack("!256s", self.startup_config_checksum))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_image_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 14)
+        obj.image_checksum = reader.read("!256s")[0].rstrip("\x00")
+        obj.startup_config_checksum = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.image_checksum != other.image_checksum: return False
+        if self.startup_config_checksum != other.startup_config_checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_image_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("image_checksum = ");
+                q.pp(self.image_checksum)
+                q.text(","); q.breakable()
+                q.text("startup_config_checksum = ");
+                q.pp(self.startup_config_checksum)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[14] = bsn_image_desc_stats_reply
+
+class bsn_image_desc_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 14
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_image_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 14)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_image_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[14] = bsn_image_desc_stats_request
+
+class bsn_lacp_convergence_notif(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 43
+
+    def __init__(self, xid=None, convergence_status=None, port_no=None, actor_sys_priority=None, actor_sys_mac=None, actor_port_priority=None, actor_port_num=None, actor_key=None, partner_sys_priority=None, partner_sys_mac=None, partner_port_priority=None, partner_port_num=None, partner_key=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if convergence_status != None:
+            self.convergence_status = convergence_status
+        else:
+            self.convergence_status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if actor_sys_priority != None:
+            self.actor_sys_priority = actor_sys_priority
+        else:
+            self.actor_sys_priority = 0
+        if actor_sys_mac != None:
+            self.actor_sys_mac = actor_sys_mac
+        else:
+            self.actor_sys_mac = [0,0,0,0,0,0]
+        if actor_port_priority != None:
+            self.actor_port_priority = actor_port_priority
+        else:
+            self.actor_port_priority = 0
+        if actor_port_num != None:
+            self.actor_port_num = actor_port_num
+        else:
+            self.actor_port_num = 0
+        if actor_key != None:
+            self.actor_key = actor_key
+        else:
+            self.actor_key = 0
+        if partner_sys_priority != None:
+            self.partner_sys_priority = partner_sys_priority
+        else:
+            self.partner_sys_priority = 0
+        if partner_sys_mac != None:
+            self.partner_sys_mac = partner_sys_mac
+        else:
+            self.partner_sys_mac = [0,0,0,0,0,0]
+        if partner_port_priority != None:
+            self.partner_port_priority = partner_port_priority
+        else:
+            self.partner_port_priority = 0
+        if partner_port_num != None:
+            self.partner_port_num = partner_port_num
+        else:
+            self.partner_port_num = 0
+        if partner_key != None:
+            self.partner_key = partner_key
+        else:
+            self.partner_key = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.convergence_status))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!H", self.actor_sys_priority))
+        packed.append(struct.pack("!6B", *self.actor_sys_mac))
+        packed.append(struct.pack("!H", self.actor_port_priority))
+        packed.append(struct.pack("!H", self.actor_port_num))
+        packed.append(struct.pack("!H", self.actor_key))
+        packed.append(struct.pack("!H", self.partner_sys_priority))
+        packed.append(struct.pack("!6B", *self.partner_sys_mac))
+        packed.append(struct.pack("!H", self.partner_port_priority))
+        packed.append(struct.pack("!H", self.partner_port_num))
+        packed.append(struct.pack("!H", self.partner_key))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_convergence_notif()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 43)
+        obj.convergence_status = reader.read("!B")[0]
+        reader.skip(3)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.actor_sys_priority = reader.read("!H")[0]
+        obj.actor_sys_mac = list(reader.read('!6B'))
+        obj.actor_port_priority = reader.read("!H")[0]
+        obj.actor_port_num = reader.read("!H")[0]
+        obj.actor_key = reader.read("!H")[0]
+        obj.partner_sys_priority = reader.read("!H")[0]
+        obj.partner_sys_mac = list(reader.read('!6B'))
+        obj.partner_port_priority = reader.read("!H")[0]
+        obj.partner_port_num = reader.read("!H")[0]
+        obj.partner_key = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.convergence_status != other.convergence_status: return False
+        if self.port_no != other.port_no: return False
+        if self.actor_sys_priority != other.actor_sys_priority: return False
+        if self.actor_sys_mac != other.actor_sys_mac: return False
+        if self.actor_port_priority != other.actor_port_priority: return False
+        if self.actor_port_num != other.actor_port_num: return False
+        if self.actor_key != other.actor_key: return False
+        if self.partner_sys_priority != other.partner_sys_priority: return False
+        if self.partner_sys_mac != other.partner_sys_mac: return False
+        if self.partner_port_priority != other.partner_port_priority: return False
+        if self.partner_port_num != other.partner_port_num: return False
+        if self.partner_key != other.partner_key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_convergence_notif {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("convergence_status = ");
+                q.text("%#x" % self.convergence_status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("actor_sys_priority = ");
+                q.text("%#x" % self.actor_sys_priority)
+                q.text(","); q.breakable()
+                q.text("actor_sys_mac = ");
+                q.text(util.pretty_mac(self.actor_sys_mac))
+                q.text(","); q.breakable()
+                q.text("actor_port_priority = ");
+                q.text("%#x" % self.actor_port_priority)
+                q.text(","); q.breakable()
+                q.text("actor_port_num = ");
+                q.text("%#x" % self.actor_port_num)
+                q.text(","); q.breakable()
+                q.text("actor_key = ");
+                q.text("%#x" % self.actor_key)
+                q.text(","); q.breakable()
+                q.text("partner_sys_priority = ");
+                q.text("%#x" % self.partner_sys_priority)
+                q.text(","); q.breakable()
+                q.text("partner_sys_mac = ");
+                q.text(util.pretty_mac(self.partner_sys_mac))
+                q.text(","); q.breakable()
+                q.text("partner_port_priority = ");
+                q.text("%#x" % self.partner_port_priority)
+                q.text(","); q.breakable()
+                q.text("partner_port_num = ");
+                q.text("%#x" % self.partner_port_num)
+                q.text(","); q.breakable()
+                q.text("partner_key = ");
+                q.text("%#x" % self.partner_key)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[43] = bsn_lacp_convergence_notif
+
+class bsn_lacp_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_lacp_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[1] = bsn_lacp_stats_reply
+
+class bsn_lacp_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[1] = bsn_lacp_stats_request
+
+class bsn_log(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 63
+
+    def __init__(self, xid=None, loglevel=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if loglevel != None:
+            self.loglevel = loglevel
+        else:
+            self.loglevel = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.loglevel))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_log()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 63)
+        obj.loglevel = reader.read("!B")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.loglevel != other.loglevel: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_log {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("loglevel = ");
+                q.text("%#x" % self.loglevel)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[63] = bsn_log
+
+class bsn_lua_command_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 66
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_command_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 66)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_command_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[66] = bsn_lua_command_reply
+
+class bsn_lua_command_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 65
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_command_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 65)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_command_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[65] = bsn_lua_command_request
+
+class bsn_lua_notification(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 67
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_notification()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 67)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_notification {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[67] = bsn_lua_notification
+
+class bsn_lua_upload(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 64
+
+    def __init__(self, xid=None, flags=None, filename=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if filename != None:
+            self.filename = filename
+        else:
+            self.filename = ""
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!64s", self.filename))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_upload()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 64)
+        obj.flags = reader.read("!H")[0]
+        obj.filename = reader.read("!64s")[0].rstrip("\x00")
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.filename != other.filename: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_upload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("filename = ");
+                q.pp(self.filename)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[64] = bsn_lua_upload
+
+class bsn_pdu_rx_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 34
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 34)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[34] = bsn_pdu_rx_reply
+
+class bsn_pdu_rx_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 33
+
+    def __init__(self, xid=None, timeout_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if timeout_ms != None:
+            self.timeout_ms = timeout_ms
+        else:
+            self.timeout_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.timeout_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 33)
+        obj.timeout_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.timeout_ms != other.timeout_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("timeout_ms = ");
+                q.text("%#x" % self.timeout_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[33] = bsn_pdu_rx_request
+
+class bsn_pdu_rx_timeout(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 35
+
+    def __init__(self, xid=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_timeout()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 35)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[35] = bsn_pdu_rx_timeout
+
+class bsn_pdu_tx_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 32
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 32)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[32] = bsn_pdu_tx_reply
+
+class bsn_pdu_tx_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 31
+
+    def __init__(self, xid=None, tx_interval_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if tx_interval_ms != None:
+            self.tx_interval_ms = tx_interval_ms
+        else:
+            self.tx_interval_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.tx_interval_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 31)
+        obj.tx_interval_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.tx_interval_ms != other.tx_interval_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("tx_interval_ms = ");
+                q.text("%#x" % self.tx_interval_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[31] = bsn_pdu_tx_request
+
+class bsn_port_counter_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_port_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_port_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_port_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[8] = bsn_port_counter_stats_reply
+
+class bsn_port_counter_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self, xid=None, flags=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_port_no(self.port_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_port_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        obj.port_no = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_port_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[8] = bsn_port_counter_stats_request
+
+class bsn_role_status(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 55
+
+    def __init__(self, xid=None, role=None, reason=None, generation_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.role))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_role_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 55)
+        obj.role = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(3)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.reason != other.reason: return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_role_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[55] = bsn_role_status
+
+class bsn_set_aux_cxns_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 59
+
+    def __init__(self, xid=None, num_aux=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if num_aux != None:
+            self.num_aux = num_aux
+        else:
+            self.num_aux = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.num_aux))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_aux_cxns_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 59)
+        obj.num_aux = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.num_aux != other.num_aux: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_aux_cxns_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("num_aux = ");
+                q.text("%#x" % self.num_aux)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[59] = bsn_set_aux_cxns_reply
+
+class bsn_set_aux_cxns_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 58
+
+    def __init__(self, xid=None, num_aux=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if num_aux != None:
+            self.num_aux = num_aux
+        else:
+            self.num_aux = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.num_aux))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_aux_cxns_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 58)
+        obj.num_aux = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.num_aux != other.num_aux: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_aux_cxns_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("num_aux = ");
+                q.text("%#x" % self.num_aux)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[58] = bsn_set_aux_cxns_request
+
+class bsn_set_lacp_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 42
+
+    def __init__(self, xid=None, status=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_lacp_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 42)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_lacp_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[42] = bsn_set_lacp_reply
+
+class bsn_set_lacp_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 41
+
+    def __init__(self, xid=None, enabled=None, port_no=None, actor_sys_priority=None, actor_sys_mac=None, actor_port_priority=None, actor_port_num=None, actor_key=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if actor_sys_priority != None:
+            self.actor_sys_priority = actor_sys_priority
+        else:
+            self.actor_sys_priority = 0
+        if actor_sys_mac != None:
+            self.actor_sys_mac = actor_sys_mac
+        else:
+            self.actor_sys_mac = [0,0,0,0,0,0]
+        if actor_port_priority != None:
+            self.actor_port_priority = actor_port_priority
+        else:
+            self.actor_port_priority = 0
+        if actor_port_num != None:
+            self.actor_port_num = actor_port_num
+        else:
+            self.actor_port_num = 0
+        if actor_key != None:
+            self.actor_key = actor_key
+        else:
+            self.actor_key = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.enabled))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!H", self.actor_sys_priority))
+        packed.append(struct.pack("!6B", *self.actor_sys_mac))
+        packed.append(struct.pack("!H", self.actor_port_priority))
+        packed.append(struct.pack("!H", self.actor_port_num))
+        packed.append(struct.pack("!H", self.actor_key))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_lacp_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 41)
+        obj.enabled = reader.read("!B")[0]
+        reader.skip(3)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.actor_sys_priority = reader.read("!H")[0]
+        obj.actor_sys_mac = list(reader.read('!6B'))
+        obj.actor_port_priority = reader.read("!H")[0]
+        obj.actor_port_num = reader.read("!H")[0]
+        obj.actor_key = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        if self.port_no != other.port_no: return False
+        if self.actor_sys_priority != other.actor_sys_priority: return False
+        if self.actor_sys_mac != other.actor_sys_mac: return False
+        if self.actor_port_priority != other.actor_port_priority: return False
+        if self.actor_port_num != other.actor_port_num: return False
+        if self.actor_key != other.actor_key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_lacp_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("actor_sys_priority = ");
+                q.text("%#x" % self.actor_sys_priority)
+                q.text(","); q.breakable()
+                q.text("actor_sys_mac = ");
+                q.text(util.pretty_mac(self.actor_sys_mac))
+                q.text(","); q.breakable()
+                q.text("actor_port_priority = ");
+                q.text("%#x" % self.actor_port_priority)
+                q.text(","); q.breakable()
+                q.text("actor_port_num = ");
+                q.text("%#x" % self.actor_port_num)
+                q.text(","); q.breakable()
+                q.text("actor_key = ");
+                q.text("%#x" % self.actor_key)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[41] = bsn_set_lacp_request
+
+class bsn_set_mirroring(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_mirroring()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_mirroring {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[3] = bsn_set_mirroring
+
+class bsn_set_pktin_suppression_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 25
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 25)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[25] = bsn_set_pktin_suppression_reply
+
+class bsn_set_pktin_suppression_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, enabled=None, idle_timeout=None, hard_timeout=None, priority=None, cookie=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.enabled))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!Q", self.cookie))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.enabled = reader.read("!B")[0]
+        reader.skip(1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.cookie = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.cookie != other.cookie: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[11] = bsn_set_pktin_suppression_request
+
+class bsn_set_switch_pipeline_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 54
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_switch_pipeline_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 54)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_switch_pipeline_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[54] = bsn_set_switch_pipeline_reply
+
+class bsn_set_switch_pipeline_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 53
+
+    def __init__(self, xid=None, pipeline=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if pipeline != None:
+            self.pipeline = pipeline
+        else:
+            self.pipeline = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!256s", self.pipeline))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_switch_pipeline_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 53)
+        obj.pipeline = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.pipeline != other.pipeline: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_switch_pipeline_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("pipeline = ");
+                q.pp(self.pipeline)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[53] = bsn_set_switch_pipeline_request
+
+class bsn_switch_pipeline_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_switch_pipeline_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_switch_pipeline_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_switch_pipeline_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[6] = bsn_switch_pipeline_stats_reply
+
+class bsn_switch_pipeline_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_switch_pipeline_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_switch_pipeline_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[6] = bsn_switch_pipeline_stats_request
+
+class bsn_table_checksum_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_checksum_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_table_checksum_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_checksum_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[11] = bsn_table_checksum_stats_reply
+
+class bsn_table_checksum_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_checksum_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_checksum_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[11] = bsn_table_checksum_stats_request
+
+class bsn_table_set_buckets_size(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 61
+
+    def __init__(self, xid=None, table_id=None, buckets_size=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if buckets_size != None:
+            self.buckets_size = buckets_size
+        else:
+            self.buckets_size = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.buckets_size))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_set_buckets_size()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 61)
+        reader.skip(1)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(2)
+        obj.buckets_size = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.buckets_size != other.buckets_size: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_set_buckets_size {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("buckets_size = ");
+                q.text("%#x" % self.buckets_size)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[61] = bsn_table_set_buckets_size
+
+class bsn_time_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 45
+
+    def __init__(self, xid=None, time_ms=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if time_ms != None:
+            self.time_ms = time_ms
+        else:
+            self.time_ms = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!Q", self.time_ms))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_time_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 45)
+        obj.time_ms = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.time_ms != other.time_ms: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_time_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("time_ms = ");
+                q.text("%#x" % self.time_ms)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[45] = bsn_time_reply
+
+class bsn_time_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 44
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_time_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 44)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_time_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[44] = bsn_time_request
+
+class bsn_virtual_port_create_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, status=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.status = reader.read("!L")[0]
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[16] = bsn_virtual_port_create_reply
+
+class bsn_virtual_port_create_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, vport=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport != None:
+            self.vport = vport
+        else:
+            self.vport = ofp.bsn_vport()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.vport.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.vport = ofp.bsn_vport.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport != other.vport: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport = ");
+                q.pp(self.vport)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[15] = bsn_virtual_port_create_request
+
+class bsn_virtual_port_remove_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 26
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 26)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[26] = bsn_virtual_port_remove_reply
+
+class bsn_virtual_port_remove_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 17
+
+    def __init__(self, xid=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 17)
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[17] = bsn_virtual_port_remove_request
+
+class bsn_vlan_counter_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_vlan_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[9] = bsn_vlan_counter_stats_reply
+
+class bsn_vlan_counter_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None, flags=None, vlan_vid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.vlan_vid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        obj.vlan_vid = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.vlan_vid != other.vlan_vid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[9] = bsn_vlan_counter_stats_request
+
+class bsn_vrf_counter_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_vrf_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[15] = bsn_vrf_counter_stats_reply
+
+class bsn_vrf_counter_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, flags=None, vrf=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if vrf != None:
+            self.vrf = vrf
+        else:
+            self.vrf = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.vrf))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.vrf = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.vrf != other.vrf: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("vrf = ");
+                q.text("%#x" % self.vrf)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[15] = bsn_vrf_counter_stats_request
+
+class desc_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None, mfr_desc=None, hw_desc=None, sw_desc=None, serial_num=None, dp_desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if mfr_desc != None:
+            self.mfr_desc = mfr_desc
+        else:
+            self.mfr_desc = ""
+        if hw_desc != None:
+            self.hw_desc = hw_desc
+        else:
+            self.hw_desc = ""
+        if sw_desc != None:
+            self.sw_desc = sw_desc
+        else:
+            self.sw_desc = ""
+        if serial_num != None:
+            self.serial_num = serial_num
+        else:
+            self.serial_num = ""
+        if dp_desc != None:
+            self.dp_desc = dp_desc
+        else:
+            self.dp_desc = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!256s", self.mfr_desc))
+        packed.append(struct.pack("!256s", self.hw_desc))
+        packed.append(struct.pack("!256s", self.sw_desc))
+        packed.append(struct.pack("!32s", self.serial_num))
+        packed.append(struct.pack("!256s", self.dp_desc))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.mfr_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.hw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.sw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.serial_num = reader.read("!32s")[0].rstrip("\x00")
+        obj.dp_desc = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.mfr_desc != other.mfr_desc: return False
+        if self.hw_desc != other.hw_desc: return False
+        if self.sw_desc != other.sw_desc: return False
+        if self.serial_num != other.serial_num: return False
+        if self.dp_desc != other.dp_desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("mfr_desc = ");
+                q.pp(self.mfr_desc)
+                q.text(","); q.breakable()
+                q.text("hw_desc = ");
+                q.pp(self.hw_desc)
+                q.text(","); q.breakable()
+                q.text("sw_desc = ");
+                q.pp(self.sw_desc)
+                q.text(","); q.breakable()
+                q.text("serial_num = ");
+                q.pp(self.serial_num)
+                q.text(","); q.breakable()
+                q.text("dp_desc = ");
+                q.pp(self.dp_desc)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[0] = desc_stats_reply
+
+class desc_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[0] = desc_stats_request
+
+class echo_reply(message):
+    version = 4
+    type = 3
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[3] = echo_reply
+
+class echo_request(message):
+    version = 4
+    type = 2
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[2] = echo_request
+
+class experimenter_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 65535
+
+    def __init__(self, xid=None, subtype=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = experimenter_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 65535)
+        obj.subtype = reader.read("!H")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("experimenter = ");
+                q.text("%#x" % self.experimenter)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[65535] = experimenter_error_msg
+
+class features_reply(message):
+    version = 4
+    type = 6
+
+    def __init__(self, xid=None, datapath_id=None, n_buffers=None, n_tables=None, auxiliary_id=None, capabilities=None, reserved=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if datapath_id != None:
+            self.datapath_id = datapath_id
+        else:
+            self.datapath_id = 0
+        if n_buffers != None:
+            self.n_buffers = n_buffers
+        else:
+            self.n_buffers = 0
+        if n_tables != None:
+            self.n_tables = n_tables
+        else:
+            self.n_tables = 0
+        if auxiliary_id != None:
+            self.auxiliary_id = auxiliary_id
+        else:
+            self.auxiliary_id = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if reserved != None:
+            self.reserved = reserved
+        else:
+            self.reserved = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.datapath_id))
+        packed.append(struct.pack("!L", self.n_buffers))
+        packed.append(struct.pack("!B", self.n_tables))
+        packed.append(struct.pack("!B", self.auxiliary_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.reserved))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.datapath_id = reader.read("!Q")[0]
+        obj.n_buffers = reader.read("!L")[0]
+        obj.n_tables = reader.read("!B")[0]
+        obj.auxiliary_id = reader.read("!B")[0]
+        reader.skip(2)
+        obj.capabilities = reader.read("!L")[0]
+        obj.reserved = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.datapath_id != other.datapath_id: return False
+        if self.n_buffers != other.n_buffers: return False
+        if self.n_tables != other.n_tables: return False
+        if self.auxiliary_id != other.auxiliary_id: return False
+        if self.capabilities != other.capabilities: return False
+        if self.reserved != other.reserved: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("datapath_id = ");
+                q.text("%#x" % self.datapath_id)
+                q.text(","); q.breakable()
+                q.text("n_buffers = ");
+                q.text("%#x" % self.n_buffers)
+                q.text(","); q.breakable()
+                q.text("n_tables = ");
+                q.text("%#x" % self.n_tables)
+                q.text(","); q.breakable()
+                q.text("auxiliary_id = ");
+                q.text("%#x" % self.auxiliary_id)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("reserved = ");
+                q.text("%#x" % self.reserved)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[6] = features_reply
+
+class features_request(message):
+    version = 4
+    type = 5
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[5] = features_request
+
+class flow_mod(message):
+    subtypes = {}
+
+    version = 4
+    type = 14
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, _command=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if _command != None:
+            self._command = _command
+        else:
+            self._command = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 25)
+        subclass = flow_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = flow_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj._command = util.unpack_fm_cmd(reader)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self._command != other._command: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[14] = flow_mod
+
+class flow_add(flow_mod):
+    version = 4
+    type = 14
+    _command = 0
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 0)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[0] = flow_add
+
+class flow_delete(flow_mod):
+    version = 4
+    type = 14
+    _command = 3
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 3)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[3] = flow_delete
+
+class flow_delete_strict(flow_mod):
+    version = 4
+    type = 14
+    _command = 4
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 4)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[4] = flow_delete_strict
+
+class flow_mod_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 5
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 5)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[5] = flow_mod_failed_error_msg
+
+class flow_modify(flow_mod):
+    version = 4
+    type = 14
+    _command = 1
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[1] = flow_modify
+
+class flow_modify_strict(flow_mod):
+    version = 4
+    type = 14
+    _command = 2
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 2)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[2] = flow_modify_strict
+
+class flow_removed(message):
+    version = 4
+    type = 11
+
+    def __init__(self, xid=None, cookie=None, priority=None, reason=None, table_id=None, duration_sec=None, duration_nsec=None, idle_timeout=None, hard_timeout=None, packet_count=None, byte_count=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_removed()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.priority != other.priority: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_removed {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[11] = flow_removed
+
+class flow_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.flow_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[1] = flow_stats_reply
+
+class flow_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[1] = flow_stats_request
+
+class get_config_reply(message):
+    version = 4
+    type = 8
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[8] = get_config_reply
+
+class get_config_request(message):
+    version = 4
+    type = 7
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[7] = get_config_request
+
+class group_mod(message):
+    subtypes = {}
+
+    version = 4
+    type = 15
+
+    def __init__(self, xid=None, command=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if command != None:
+            self.command = command
+        else:
+            self.command = 0
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = group_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = group_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.command = reader.read("!H")[0]
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.command != other.command: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[15] = group_mod
+
+class group_add(group_mod):
+    version = 4
+    type = 15
+    command = 0
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 0)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[0] = group_add
+
+class group_delete(group_mod):
+    version = 4
+    type = 15
+    command = 2
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[2] = group_delete
+
+class group_desc_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[7] = group_desc_stats_reply
+
+class group_desc_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[7] = group_desc_stats_request
+
+class group_features_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 8
+
+    def __init__(self, xid=None, flags=None, types=None, capabilities=None, max_groups_all=None, max_groups_select=None, max_groups_indirect=None, max_groups_ff=None, actions_all=None, actions_select=None, actions_indirect=None, actions_ff=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if types != None:
+            self.types = types
+        else:
+            self.types = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if max_groups_all != None:
+            self.max_groups_all = max_groups_all
+        else:
+            self.max_groups_all = 0
+        if max_groups_select != None:
+            self.max_groups_select = max_groups_select
+        else:
+            self.max_groups_select = 0
+        if max_groups_indirect != None:
+            self.max_groups_indirect = max_groups_indirect
+        else:
+            self.max_groups_indirect = 0
+        if max_groups_ff != None:
+            self.max_groups_ff = max_groups_ff
+        else:
+            self.max_groups_ff = 0
+        if actions_all != None:
+            self.actions_all = actions_all
+        else:
+            self.actions_all = 0
+        if actions_select != None:
+            self.actions_select = actions_select
+        else:
+            self.actions_select = 0
+        if actions_indirect != None:
+            self.actions_indirect = actions_indirect
+        else:
+            self.actions_indirect = 0
+        if actions_ff != None:
+            self.actions_ff = actions_ff
+        else:
+            self.actions_ff = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.types))
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.max_groups_all))
+        packed.append(struct.pack("!L", self.max_groups_select))
+        packed.append(struct.pack("!L", self.max_groups_indirect))
+        packed.append(struct.pack("!L", self.max_groups_ff))
+        packed.append(struct.pack("!L", self.actions_all))
+        packed.append(struct.pack("!L", self.actions_select))
+        packed.append(struct.pack("!L", self.actions_indirect))
+        packed.append(struct.pack("!L", self.actions_ff))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_features_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 8)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.types = reader.read("!L")[0]
+        obj.capabilities = reader.read("!L")[0]
+        obj.max_groups_all = reader.read("!L")[0]
+        obj.max_groups_select = reader.read("!L")[0]
+        obj.max_groups_indirect = reader.read("!L")[0]
+        obj.max_groups_ff = reader.read("!L")[0]
+        obj.actions_all = reader.read("!L")[0]
+        obj.actions_select = reader.read("!L")[0]
+        obj.actions_indirect = reader.read("!L")[0]
+        obj.actions_ff = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.types != other.types: return False
+        if self.capabilities != other.capabilities: return False
+        if self.max_groups_all != other.max_groups_all: return False
+        if self.max_groups_select != other.max_groups_select: return False
+        if self.max_groups_indirect != other.max_groups_indirect: return False
+        if self.max_groups_ff != other.max_groups_ff: return False
+        if self.actions_all != other.actions_all: return False
+        if self.actions_select != other.actions_select: return False
+        if self.actions_indirect != other.actions_indirect: return False
+        if self.actions_ff != other.actions_ff: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_features_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("types = ");
+                q.text("%#x" % self.types)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("max_groups_all = ");
+                q.text("%#x" % self.max_groups_all)
+                q.text(","); q.breakable()
+                q.text("max_groups_select = ");
+                q.text("%#x" % self.max_groups_select)
+                q.text(","); q.breakable()
+                q.text("max_groups_indirect = ");
+                q.text("%#x" % self.max_groups_indirect)
+                q.text(","); q.breakable()
+                q.text("max_groups_ff = ");
+                q.text("%#x" % self.max_groups_ff)
+                q.text(","); q.breakable()
+                q.text("actions_all = ");
+                q.text("%#x" % self.actions_all)
+                q.text(","); q.breakable()
+                q.text("actions_select = ");
+                q.text("%#x" % self.actions_select)
+                q.text(","); q.breakable()
+                q.text("actions_indirect = ");
+                q.text("%#x" % self.actions_indirect)
+                q.text(","); q.breakable()
+                q.text("actions_ff = ");
+                q.text("%#x" % self.actions_ff)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[8] = group_features_stats_reply
+
+class group_features_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 8
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_features_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 8)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_features_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[8] = group_features_stats_request
+
+class group_mod_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 6
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 6)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[6] = group_mod_failed_error_msg
+
+class group_modify(group_mod):
+    version = 4
+    type = 15
+    command = 1
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 1)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[1] = group_modify
+
+class group_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[6] = group_stats_reply
+
+class group_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, group_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.group_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[6] = group_stats_request
+
+class hello(message):
+    version = 4
+    type = 0
+
+    def __init__(self, xid=None, elements=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if elements != None:
+            self.elements = elements
+        else:
+            self.elements = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(loxi.generic_util.pack_list(self.elements))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.elements = loxi.generic_util.unpack_list(reader, ofp.common.hello_elem.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.elements != other.elements: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("elements = ");
+                q.pp(self.elements)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[0] = hello
+
+class hello_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 0
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 0)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[0] = hello_failed_error_msg
+
+class meter_config_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 10
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_config_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 10)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.meter_band.meter_band.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_config_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[10] = meter_config_stats_reply
+
+class meter_config_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 10
+
+    def __init__(self, xid=None, flags=None, meter_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_config_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 10)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.meter_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_config_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[10] = meter_config_stats_request
+
+class meter_features_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 11
+
+    def __init__(self, xid=None, flags=None, features=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if features != None:
+            self.features = features
+        else:
+            self.features = ofp.meter_features()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(self.features.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_features_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 11)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.features = ofp.meter_features.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.features != other.features: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_features_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("features = ");
+                q.pp(self.features)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[11] = meter_features_stats_reply
+
+class meter_features_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 11
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_features_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 11)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_features_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[11] = meter_features_stats_request
+
+class meter_mod(message):
+    version = 4
+    type = 29
+
+    def __init__(self, xid=None, command=None, flags=None, meter_id=None, meters=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if command != None:
+            self.command = command
+        else:
+            self.command = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        if meters != None:
+            self.meters = meters
+        else:
+            self.meters = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append(loxi.generic_util.pack_list(self.meters))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 29)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.command = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.meter_id = reader.read("!L")[0]
+        obj.meters = loxi.generic_util.unpack_list(reader, ofp.meter_band.meter_band.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.command != other.command: return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        if self.meters != other.meters: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("command = ");
+                q.text("%#x" % self.command)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+                q.text(","); q.breakable()
+                q.text("meters = ");
+                q.pp(self.meters)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[29] = meter_mod
+
+class meter_mod_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 12
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 12)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[12] = meter_mod_failed_error_msg
+
+class meter_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 9
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 9)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.meter_stats.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[9] = meter_stats_reply
+
+class meter_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 9
+
+    def __init__(self, xid=None, flags=None, meter_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 9)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.meter_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[9] = meter_stats_request
+
+class nicira_header(experimenter):
+    subtypes = {}
+
+    version = 4
+    type = 4
+    experimenter = 8992
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = nicira_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira_header
+
+class packet_in(message):
+    version = 4
+    type = 10
+
+    def __init__(self, xid=None, buffer_id=None, total_len=None, reason=None, table_id=None, cookie=None, match=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if total_len != None:
+            self.total_len = total_len
+        else:
+            self.total_len = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(struct.pack("!H", self.total_len))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(self.match.pack())
+        packed.append('\x00' * 2)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_in()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.total_len = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        reader.skip(2)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.total_len != other.total_len: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.cookie != other.cookie: return False
+        if self.match != other.match: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("total_len = ");
+                q.text("%#x" % self.total_len)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[10] = packet_in
+
+class packet_out(message):
+    version = 4
+    type = 13
+
+    def __init__(self, xid=None, buffer_id=None, in_port=None, actions=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(struct.pack("!H", 0)) # placeholder for actions_len at index 6
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        packed[6] = struct.pack("!H", len(packed[-1]))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_out()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.in_port = util.unpack_port_no(reader)
+        _actions_len = reader.read("!H")[0]
+        reader.skip(6)
+        obj.actions = loxi.generic_util.unpack_list(reader.slice(_actions_len), ofp.action.action.unpack)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.in_port != other.in_port: return False
+        if self.actions != other.actions: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[13] = packet_out
+
+class port_desc_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 13
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 13)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.port_desc.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[13] = port_desc_stats_reply
+
+class port_desc_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 13
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 13)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[13] = port_desc_stats_request
+
+class port_mod(message):
+    version = 4
+    type = 16
+
+    def __init__(self, xid=None, port_no=None, hw_addr=None, config=None, mask=None, advertise=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        if advertise != None:
+            self.advertise = advertise
+        else:
+            self.advertise = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.mask))
+        packed.append(struct.pack("!L", self.advertise))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.config = reader.read("!L")[0]
+        obj.mask = reader.read("!L")[0]
+        obj.advertise = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.config != other.config: return False
+        if self.mask != other.mask: return False
+        if self.advertise != other.advertise: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+                q.text(","); q.breakable()
+                q.text("advertise = ");
+                q.text("%#x" % self.advertise)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[16] = port_mod
+
+class port_mod_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 7
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 7)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[7] = port_mod_failed_error_msg
+
+class port_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.port_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[4] = port_stats_reply
+
+class port_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[4] = port_stats_request
+
+class port_status(message):
+    version = 4
+    type = 12
+
+    def __init__(self, xid=None, reason=None, desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if desc != None:
+            self.desc = desc
+        else:
+            self.desc = ofp.port_desc()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 7)
+        packed.append(self.desc.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(7)
+        obj.desc = ofp.port_desc.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.reason != other.reason: return False
+        if self.desc != other.desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("desc = ");
+                q.pp(self.desc)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[12] = port_status
+
+class queue_get_config_reply(message):
+    version = 4
+    type = 23
+
+    def __init__(self, xid=None, port=None, queues=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if queues != None:
+            self.queues = queues
+        else:
+            self.queues = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.queues))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 23)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.queues = loxi.generic_util.unpack_list(reader, ofp.common.packet_queue.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        if self.queues != other.queues: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("queues = ");
+                q.pp(self.queues)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[23] = queue_get_config_reply
+
+class queue_get_config_request(message):
+    version = 4
+    type = 22
+
+    def __init__(self, xid=None, port=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 22)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+            q.breakable()
+        q.text('}')
+
+message.subtypes[22] = queue_get_config_request
+
+class queue_op_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 9
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_op_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 9)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_op_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[9] = queue_op_failed_error_msg
+
+class queue_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.queue_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[5] = queue_stats_reply
+
+class queue_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, port_no=None, queue_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[5] = queue_stats_request
+
+class role_reply(message):
+    version = 4
+    type = 25
+
+    def __init__(self, xid=None, role=None, generation_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 25)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        reader.skip(4)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[25] = role_reply
+
+class role_request(message):
+    version = 4
+    type = 24
+
+    def __init__(self, xid=None, role=None, generation_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 24)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        reader.skip(4)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[24] = role_request
+
+class role_request_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 11
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_request_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 11)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_request_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[11] = role_request_failed_error_msg
+
+class set_config(message):
+    version = 4
+    type = 9
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_config()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_config {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[9] = set_config
+
+class switch_config_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 10
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = switch_config_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 10)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("switch_config_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[10] = switch_config_failed_error_msg
+
+class table_features_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 13
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 13)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[13] = table_features_failed_error_msg
+
+class table_features_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 12
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 12)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_features.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[12] = table_features_stats_reply
+
+class table_features_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 12
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 12)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_features.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[12] = table_features_stats_request
+
+class table_mod(message):
+    version = 4
+    type = 17
+
+    def __init__(self, xid=None, table_id=None, config=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.config))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.config = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.config != other.config: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[17] = table_mod
+
+class table_mod_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 8
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 8)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[8] = table_mod_failed_error_msg
+
+class table_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[3] = table_stats_reply
+
+class table_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[3] = table_stats_request
+
+
+def parse_header(buf):
+    if len(buf) < 8:
+        raise loxi.ProtocolError("too short to be an OpenFlow message")
+    return struct.unpack_from("!BBHL", buf)
+
+def parse_message(buf):
+    msg_ver, msg_type, msg_len, msg_xid = parse_header(buf)
+    if msg_ver != ofp.OFP_VERSION and msg_type != ofp.OFPT_HELLO:
+        raise loxi.ProtocolError("wrong OpenFlow version (expected %d, got %d)" % (ofp.OFP_VERSION, msg_ver))
+    if len(buf) != msg_len:
+        raise loxi.ProtocolError("incorrect message size")
+    return message.unpack(loxi.generic_util.OFReader(buf))
diff --git a/Fabric/Utilities/src/python/loxi/of13/meter_band.py b/Fabric/Utilities/src/python/loxi/of13/meter_band.py
new file mode 100644
index 0000000..f0ed683
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/meter_band.py
@@ -0,0 +1,275 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class meter_band(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = meter_band.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = meter_band()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_band {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class drop(meter_band):
+    type = 1
+
+    def __init__(self, rate=None, burst_size=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        if burst_size != None:
+            self.burst_size = burst_size
+        else:
+            self.burst_size = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.rate))
+        packed.append(struct.pack("!L", self.burst_size))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = drop()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.rate = reader.read("!L")[0]
+        obj.burst_size = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        if self.burst_size != other.burst_size: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("drop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+                q.text(","); q.breakable()
+                q.text("burst_size = ");
+                q.text("%#x" % self.burst_size)
+            q.breakable()
+        q.text('}')
+
+meter_band.subtypes[1] = drop
+
+class dscp_remark(meter_band):
+    type = 2
+
+    def __init__(self, rate=None, burst_size=None, prec_level=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        if burst_size != None:
+            self.burst_size = burst_size
+        else:
+            self.burst_size = 0
+        if prec_level != None:
+            self.prec_level = prec_level
+        else:
+            self.prec_level = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.rate))
+        packed.append(struct.pack("!L", self.burst_size))
+        packed.append(struct.pack("!B", self.prec_level))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dscp_remark()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.rate = reader.read("!L")[0]
+        obj.burst_size = reader.read("!L")[0]
+        obj.prec_level = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        if self.burst_size != other.burst_size: return False
+        if self.prec_level != other.prec_level: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dscp_remark {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+                q.text(","); q.breakable()
+                q.text("burst_size = ");
+                q.text("%#x" % self.burst_size)
+                q.text(","); q.breakable()
+                q.text("prec_level = ");
+                q.text("%#x" % self.prec_level)
+            q.breakable()
+        q.text('}')
+
+meter_band.subtypes[2] = dscp_remark
+
+class experimenter(meter_band):
+    type = 65535
+
+    def __init__(self, rate=None, burst_size=None, experimenter=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        if burst_size != None:
+            self.burst_size = burst_size
+        else:
+            self.burst_size = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.rate))
+        packed.append(struct.pack("!L", self.burst_size))
+        packed.append(struct.pack("!L", self.experimenter))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.rate = reader.read("!L")[0]
+        obj.burst_size = reader.read("!L")[0]
+        obj.experimenter = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        if self.burst_size != other.burst_size: return False
+        if self.experimenter != other.experimenter: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+                q.text(","); q.breakable()
+                q.text("burst_size = ");
+                q.text("%#x" % self.burst_size)
+                q.text(","); q.breakable()
+                q.text("experimenter = ");
+                q.text("%#x" % self.experimenter)
+            q.breakable()
+        q.text('}')
+
+meter_band.subtypes[65535] = experimenter
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of13/oxm.py b/Fabric/Utilities/src/python/loxi/of13/oxm.py
new file mode 100755
index 0000000..a2c0a23
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/oxm.py
@@ -0,0 +1,6329 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class oxm(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type_len=None):
+        if type_len != None:
+            self.type_len = type_len
+        else:
+            self.type_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 0)
+        subclass = oxm.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = oxm()
+        obj.type_len = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type_len != other.type_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("oxm {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class arp_op(oxm):
+    type_len = 2147494402
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_op()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494402)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_op {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494402] = arp_op
+
+class arp_op_masked(oxm):
+    type_len = 2147494660
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_op_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494660)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_op_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494660] = arp_op_masked
+
+class arp_sha(oxm):
+    type_len = 2147495942
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_sha()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495942)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_sha {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495942] = arp_sha
+
+class arp_sha_masked(oxm):
+    type_len = 2147496204
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_sha_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496204)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_sha_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496204] = arp_sha_masked
+
+class arp_spa(oxm):
+    type_len = 2147494916
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_spa()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494916)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_spa {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494916] = arp_spa
+
+class arp_spa_masked(oxm):
+    type_len = 2147495176
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_spa_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495176)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_spa_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495176] = arp_spa_masked
+
+class arp_tha(oxm):
+    type_len = 2147496454
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tha()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496454)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tha {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496454] = arp_tha
+
+class arp_tha_masked(oxm):
+    type_len = 2147496716
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tha_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496716)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tha_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496716] = arp_tha_masked
+
+class arp_tpa(oxm):
+    type_len = 2147495428
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tpa()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495428)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tpa {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495428] = arp_tpa
+
+class arp_tpa_masked(oxm):
+    type_len = 2147495688
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tpa_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495688)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tpa_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495688] = arp_tpa_masked
+
+class bsn_egr_port_group_id(oxm):
+    type_len = 200196
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_egr_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200196)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_egr_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200196] = bsn_egr_port_group_id
+
+class bsn_egr_port_group_id_masked(oxm):
+    type_len = 200456
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_egr_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200456)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_egr_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200456] = bsn_egr_port_group_id_masked
+
+class bsn_global_vrf_allowed(oxm):
+    type_len = 198145
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_global_vrf_allowed()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198145)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_global_vrf_allowed {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198145] = bsn_global_vrf_allowed
+
+class bsn_global_vrf_allowed_masked(oxm):
+    type_len = 198402
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_global_vrf_allowed_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198402)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_global_vrf_allowed_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198402] = bsn_global_vrf_allowed_masked
+
+class bsn_in_ports_128(oxm):
+    type_len = 196624
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_128(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_128()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 196624)
+        obj.value = util.unpack_bitmap_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_128 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[196624] = bsn_in_ports_128
+
+class bsn_in_ports_128_masked(oxm):
+    type_len = 196896
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_128(self.value))
+        packed.append(util.pack_bitmap_128(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_128_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 196896)
+        obj.value = util.unpack_bitmap_128(reader)
+        obj.value_mask = util.unpack_bitmap_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_128_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[196896] = bsn_in_ports_128_masked
+
+class bsn_in_ports_512(oxm):
+    type_len = 206400
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_512(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_512()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206400)
+        obj.value = util.unpack_bitmap_512(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_512 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206400] = bsn_in_ports_512
+
+class bsn_in_ports_512_masked(oxm):
+    type_len = 206720
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_512(self.value))
+        packed.append(util.pack_bitmap_512(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_512_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206720)
+        obj.value = util.unpack_bitmap_512(reader)
+        obj.value_mask = util.unpack_bitmap_512(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_512_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206720] = bsn_in_ports_512_masked
+
+class bsn_ingress_port_group_id(oxm):
+    type_len = 206852
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_ingress_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206852)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_ingress_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206852] = bsn_ingress_port_group_id
+
+class bsn_ingress_port_group_id_masked(oxm):
+    type_len = 207112
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_ingress_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207112)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_ingress_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207112] = bsn_ingress_port_group_id_masked
+
+class bsn_inner_eth_dst(oxm):
+    type_len = 207878
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207878)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207878] = bsn_inner_eth_dst
+
+class bsn_inner_eth_dst_masked(oxm):
+    type_len = 208140
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208140)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208140] = bsn_inner_eth_dst_masked
+
+class bsn_inner_eth_src(oxm):
+    type_len = 208390
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208390)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208390] = bsn_inner_eth_src
+
+class bsn_inner_eth_src_masked(oxm):
+    type_len = 208652
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208652)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208652] = bsn_inner_eth_src_masked
+
+class bsn_inner_vlan_vid(oxm):
+    type_len = 208898
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_vlan_vid()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208898)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208898] = bsn_inner_vlan_vid
+
+class bsn_inner_vlan_vid_masked(oxm):
+    type_len = 209156
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_vlan_vid_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 209156)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_vlan_vid_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[209156] = bsn_inner_vlan_vid_masked
+
+class bsn_l2_cache_hit(oxm):
+    type_len = 205825
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l2_cache_hit()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205825)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l2_cache_hit {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205825] = bsn_l2_cache_hit
+
+class bsn_l2_cache_hit_masked(oxm):
+    type_len = 206082
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l2_cache_hit_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206082)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l2_cache_hit_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206082] = bsn_l2_cache_hit_masked
+
+class bsn_l3_dst_class_id(oxm):
+    type_len = 199684
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_dst_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199684)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_dst_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199684] = bsn_l3_dst_class_id
+
+class bsn_l3_dst_class_id_masked(oxm):
+    type_len = 199944
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_dst_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199944)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_dst_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199944] = bsn_l3_dst_class_id_masked
+
+class bsn_l3_interface_class_id(oxm):
+    type_len = 198660
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_interface_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198660)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_interface_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198660] = bsn_l3_interface_class_id
+
+class bsn_l3_interface_class_id_masked(oxm):
+    type_len = 198920
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_interface_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198920)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_interface_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198920] = bsn_l3_interface_class_id_masked
+
+class bsn_l3_src_class_id(oxm):
+    type_len = 199172
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_src_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199172)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_src_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199172] = bsn_l3_src_class_id
+
+class bsn_l3_src_class_id_masked(oxm):
+    type_len = 199432
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_src_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199432)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_src_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199432] = bsn_l3_src_class_id_masked
+
+class bsn_lag_id(oxm):
+    type_len = 197124
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lag_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197124)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lag_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197124] = bsn_lag_id
+
+class bsn_lag_id_masked(oxm):
+    type_len = 197384
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lag_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197384)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lag_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197384] = bsn_lag_id_masked
+
+class bsn_tcp_flags(oxm):
+    type_len = 204802
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_tcp_flags()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204802)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tcp_flags {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204802] = bsn_tcp_flags
+
+class bsn_tcp_flags_masked(oxm):
+    type_len = 205060
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_tcp_flags_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205060)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tcp_flags_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205060] = bsn_tcp_flags_masked
+
+class bsn_udf0(oxm):
+    type_len = 200708
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf0()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200708)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf0 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200708] = bsn_udf0
+
+class bsn_udf0_masked(oxm):
+    type_len = 200968
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf0_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200968)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf0_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200968] = bsn_udf0_masked
+
+class bsn_udf1(oxm):
+    type_len = 201220
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf1()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201220)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf1 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201220] = bsn_udf1
+
+class bsn_udf1_masked(oxm):
+    type_len = 201480
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf1_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201480)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf1_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201480] = bsn_udf1_masked
+
+class bsn_udf2(oxm):
+    type_len = 201732
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf2()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201732)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf2 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201732] = bsn_udf2
+
+class bsn_udf2_masked(oxm):
+    type_len = 201992
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf2_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201992)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf2_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201992] = bsn_udf2_masked
+
+class bsn_udf3(oxm):
+    type_len = 202244
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf3()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202244)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202244] = bsn_udf3
+
+class bsn_udf3_masked(oxm):
+    type_len = 202504
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf3_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202504)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf3_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202504] = bsn_udf3_masked
+
+class bsn_udf4(oxm):
+    type_len = 202756
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf4()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202756)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf4 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202756] = bsn_udf4
+
+class bsn_udf4_masked(oxm):
+    type_len = 203016
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf4_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203016)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf4_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203016] = bsn_udf4_masked
+
+class bsn_udf5(oxm):
+    type_len = 203268
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf5()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203268)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf5 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203268] = bsn_udf5
+
+class bsn_udf5_masked(oxm):
+    type_len = 203528
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf5_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203528)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf5_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203528] = bsn_udf5_masked
+
+class bsn_udf6(oxm):
+    type_len = 203780
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf6()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203780)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf6 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203780] = bsn_udf6
+
+class bsn_udf6_masked(oxm):
+    type_len = 204040
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf6_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204040)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf6_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204040] = bsn_udf6_masked
+
+class bsn_udf7(oxm):
+    type_len = 204292
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf7()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204292)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf7 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204292] = bsn_udf7
+
+class bsn_udf7_masked(oxm):
+    type_len = 204552
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf7_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204552)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf7_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204552] = bsn_udf7_masked
+
+class bsn_vlan_xlate_port_group_id(oxm):
+    type_len = 205316
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_xlate_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205316)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_xlate_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205316] = bsn_vlan_xlate_port_group_id
+
+class bsn_vlan_xlate_port_group_id_masked(oxm):
+    type_len = 205576
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_xlate_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205576)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_xlate_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205576] = bsn_vlan_xlate_port_group_id_masked
+
+class bsn_vrf(oxm):
+    type_len = 197636
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197636)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197636] = bsn_vrf
+
+class bsn_vrf_masked(oxm):
+    type_len = 197896
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197896)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197896] = bsn_vrf_masked
+
+class bsn_vxlan_network_id(oxm):
+    type_len = 207364
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vxlan_network_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207364)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vxlan_network_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207364] = bsn_vxlan_network_id
+
+class bsn_vxlan_network_id_masked(oxm):
+    type_len = 207624
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vxlan_network_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207624)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vxlan_network_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207624] = bsn_vxlan_network_id_masked
+
+class eth_dst(oxm):
+    type_len = 2147485190
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485190)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485190] = eth_dst
+
+class eth_dst_masked(oxm):
+    type_len = 2147485452
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485452)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485452] = eth_dst_masked
+
+class eth_src(oxm):
+    type_len = 2147485702
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485702)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485702] = eth_src
+
+class eth_src_masked(oxm):
+    type_len = 2147485964
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485964)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485964] = eth_src_masked
+
+class eth_type(oxm):
+    type_len = 2147486210
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486210)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486210] = eth_type
+
+class eth_type_masked(oxm):
+    type_len = 2147486468
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486468)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486468] = eth_type_masked
+
+class icmpv4_code(oxm):
+    type_len = 2147493889
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_code()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493889)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493889] = icmpv4_code
+
+class icmpv4_code_masked(oxm):
+    type_len = 2147494146
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_code_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494146)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_code_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494146] = icmpv4_code_masked
+
+class icmpv4_type(oxm):
+    type_len = 2147493377
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493377)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493377] = icmpv4_type
+
+class icmpv4_type_masked(oxm):
+    type_len = 2147493634
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493634)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493634] = icmpv4_type_masked
+
+class icmpv6_code(oxm):
+    type_len = 2147499009
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_code()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499009)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499009] = icmpv6_code
+
+class icmpv6_code_masked(oxm):
+    type_len = 2147499266
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_code_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499266)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_code_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499266] = icmpv6_code_masked
+
+class icmpv6_type(oxm):
+    type_len = 2147498497
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498497)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498497] = icmpv6_type
+
+class icmpv6_type_masked(oxm):
+    type_len = 2147498754
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498754)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498754] = icmpv6_type_masked
+
+class in_phy_port(oxm):
+    type_len = 2147484164
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_phy_port()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484164)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_phy_port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484164] = in_phy_port
+
+class in_phy_port_masked(oxm):
+    type_len = 2147484424
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        packed.append(util.pack_port_no(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_phy_port_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484424)
+        obj.value = util.unpack_port_no(reader)
+        obj.value_mask = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_phy_port_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_port(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484424] = in_phy_port_masked
+
+class in_port(oxm):
+    type_len = 2147483652
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_port()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147483652)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147483652] = in_port
+
+class in_port_masked(oxm):
+    type_len = 2147483912
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        packed.append(util.pack_port_no(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_port_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147483912)
+        obj.value = util.unpack_port_no(reader)
+        obj.value_mask = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_port_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_port(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147483912] = in_port_masked
+
+class ip_dscp(oxm):
+    type_len = 2147487745
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_dscp()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487745)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_dscp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487745] = ip_dscp
+
+class ip_dscp_masked(oxm):
+    type_len = 2147488002
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_dscp_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488002)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_dscp_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488002] = ip_dscp_masked
+
+class ip_ecn(oxm):
+    type_len = 2147488257
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_ecn()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488257)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_ecn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488257] = ip_ecn
+
+class ip_ecn_masked(oxm):
+    type_len = 2147488514
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_ecn_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488514)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_ecn_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488514] = ip_ecn_masked
+
+class ip_proto(oxm):
+    type_len = 2147488769
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488769)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488769] = ip_proto
+
+class ip_proto_masked(oxm):
+    type_len = 2147489026
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489026)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489026] = ip_proto_masked
+
+class ipv4_dst(oxm):
+    type_len = 2147489796
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489796)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489796] = ipv4_dst
+
+class ipv4_dst_masked(oxm):
+    type_len = 2147490056
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490056)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490056] = ipv4_dst_masked
+
+class ipv4_src(oxm):
+    type_len = 2147489284
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489284)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489284] = ipv4_src
+
+class ipv4_src_masked(oxm):
+    type_len = 2147489544
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489544)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489544] = ipv4_src_masked
+
+class ipv6_dst(oxm):
+    type_len = 2147497488
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497488)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497488] = ipv6_dst
+
+class ipv6_dst_masked(oxm):
+    type_len = 2147497760
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497760)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497760] = ipv6_dst_masked
+
+class ipv6_exthdr(oxm):
+    type_len = 2147503618
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_exthdr()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503618)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_exthdr {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503618] = ipv6_exthdr
+
+class ipv6_exthdr_masked(oxm):
+    type_len = 2147503876
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_exthdr_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503876)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_exthdr_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503876] = ipv6_exthdr_masked
+
+class ipv6_flabel(oxm):
+    type_len = 2147497988
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_flabel()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497988)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_flabel {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497988] = ipv6_flabel
+
+class ipv6_flabel_masked(oxm):
+    type_len = 2147498248
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_flabel_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498248)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_flabel_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498248] = ipv6_flabel_masked
+
+class ipv6_nd_sll(oxm):
+    type_len = 2147500038
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_sll()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500038)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_sll {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500038] = ipv6_nd_sll
+
+class ipv6_nd_sll_masked(oxm):
+    type_len = 2147500300
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_sll_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500300)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_sll_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500300] = ipv6_nd_sll_masked
+
+class ipv6_nd_target(oxm):
+    type_len = 2147499536
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_target()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499536)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_target {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499536] = ipv6_nd_target
+
+class ipv6_nd_target_masked(oxm):
+    type_len = 2147499808
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_target_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499808)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_target_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499808] = ipv6_nd_target_masked
+
+class ipv6_nd_tll(oxm):
+    type_len = 2147500550
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_tll()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500550)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_tll {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500550] = ipv6_nd_tll
+
+class ipv6_nd_tll_masked(oxm):
+    type_len = 2147500812
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_tll_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500812)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_tll_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500812] = ipv6_nd_tll_masked
+
+class ipv6_src(oxm):
+    type_len = 2147496976
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496976)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496976] = ipv6_src
+
+class ipv6_src_masked(oxm):
+    type_len = 2147497248
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497248)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497248] = ipv6_src_masked
+
+class metadata(oxm):
+    type_len = 2147484680
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = metadata()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484680)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484680] = metadata
+
+class metadata_masked(oxm):
+    type_len = 2147484944
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        packed.append(struct.pack("!Q", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = metadata_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484944)
+        obj.value = reader.read("!Q")[0]
+        obj.value_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("metadata_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484944] = metadata_masked
+
+class mpls_bos(oxm):
+    type_len = 2147502081
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_bos()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147502081)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_bos {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147502081] = mpls_bos
+
+class mpls_bos_masked(oxm):
+    type_len = 2147502338
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_bos_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147502338)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_bos_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147502338] = mpls_bos_masked
+
+class mpls_label(oxm):
+    type_len = 2147501060
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501060)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501060] = mpls_label
+
+class mpls_label_masked(oxm):
+    type_len = 2147501320
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501320)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501320] = mpls_label_masked
+
+class mpls_tc(oxm):
+    type_len = 2147501569
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_tc()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501569)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_tc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501569] = mpls_tc
+
+class mpls_tc_masked(oxm):
+    type_len = 2147501826
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_tc_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501826)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_tc_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501826] = mpls_tc_masked
+
+class sctp_dst(oxm):
+    type_len = 2147492866
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492866)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492866] = sctp_dst
+
+class sctp_dst_masked(oxm):
+    type_len = 2147493124
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493124)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493124] = sctp_dst_masked
+
+class sctp_src(oxm):
+    type_len = 2147492354
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492354)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492354] = sctp_src
+
+class sctp_src_masked(oxm):
+    type_len = 2147492612
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492612)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492612] = sctp_src_masked
+
+class tcp_dst(oxm):
+    type_len = 2147490818
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490818)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490818] = tcp_dst
+
+class tcp_dst_masked(oxm):
+    type_len = 2147491076
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491076)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491076] = tcp_dst_masked
+
+class tcp_src(oxm):
+    type_len = 2147490306
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490306)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490306] = tcp_src
+
+class tcp_src_masked(oxm):
+    type_len = 2147490564
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490564)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490564] = tcp_src_masked
+
+class tunnel_id(oxm):
+    type_len = 2147503112
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503112)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503112] = tunnel_id
+
+class tunnel_id_masked(oxm):
+    type_len = 2147503376
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        packed.append(struct.pack("!Q", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503376)
+        obj.value = reader.read("!Q")[0]
+        obj.value_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503376] = tunnel_id_masked
+
+class tunnel_ipv4_dst(oxm):
+    type_len = 81924
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81924)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81924] = tunnel_ipv4_dst
+
+class tunnel_ipv4_dst_masked(oxm):
+    type_len = 82184
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 82184)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[82184] = tunnel_ipv4_dst_masked
+
+class tunnel_ipv4_src(oxm):
+    type_len = 81412
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81412)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81412] = tunnel_ipv4_src
+
+class tunnel_ipv4_src_masked(oxm):
+    type_len = 81672
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81672)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81672] = tunnel_ipv4_src_masked
+
+class udp_dst(oxm):
+    type_len = 2147491842
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491842)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491842] = udp_dst
+
+class udp_dst_masked(oxm):
+    type_len = 2147492100
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492100)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492100] = udp_dst_masked
+
+class udp_src(oxm):
+    type_len = 2147491330
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491330)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491330] = udp_src
+
+class udp_src_masked(oxm):
+    type_len = 2147491588
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491588)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491588] = udp_src_masked
+
+class vlan_pcp(oxm):
+    type_len = 2147487233
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487233)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487233] = vlan_pcp
+
+class vlan_pcp_masked(oxm):
+    type_len = 2147487490
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487490)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487490] = vlan_pcp_masked
+
+class vlan_vid(oxm):
+    type_len = 2147486722
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486722)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486722] = vlan_vid
+
+class vlan_vid_masked(oxm):
+    type_len = 2147486980
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486980)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486980] = vlan_vid_masked
+
+OFDPA_EXPERIMETER =0x00001018
+
+OFDPA_EXP_TYPE_VRF          =1
+OFDPA_EXP_TYPE_TRAFFIC_CLASS=2
+OFDPA_EXP_TYPE_COLOR        =3
+OFDPA_EXP_TYPE_DEI          =4
+OFDPA_EXP_TYPE_QOS_INDEX    =5
+OFDPA_EXP_TYPE_LMEP_ID      =6
+OFDPA_EXP_TYPE_MPLS_TTL     =7
+OFDPA_EXP_TYPE_MPLS_L2_PORT =8
+OFDPA_EXP_TYPE_OVID         =10
+OFDPA_EXP_TYPE_MPLS_DATA_FIRST_NIBBLE=11,
+OFDPA_EXP_TYPE_ACH_CHANNEL  =12
+OFDPA_EXP_TYPE_NEXT_LABLE_IS_GAL=13
+OFDPA_EXP_TYPE_OAM_Y1731_MDL=14
+OFDPA_EXP_TYPE_OAM_Y1731_OPCODE=15
+OFDPA_EXP_TYPE_COLOR_ACTION_INDEX=16
+OFDPA_EXP_TYPE_TXFCL        =17
+OFDPA_EXP_TYPE_RXFCL        =18
+OFDPA_EXP_TYPE_MPLS_TYPE    = 23
+OFDPA_EXP_TYPE_RX_TIMESAMP  =19
+
+OFDPA_EXP_TYPE_ACTSET_OUTPUT=43
+OFDPA_EXP_TYPE_ALLOW_VLAN_TRANSLATION=24
+
+VPWS                        = 1
+TUNNEL_ID_BASE              = 0x10000
+TUNNEL_ID_BASE_CROSS_CONNECT = 0x20000
+L3_PHP                      = 32
+
+class exp1ByteValue(oxm):
+    type_len = 0xffff0005
+
+    def __init__(self, exp_type=0, value=None):
+        if value != None:
+            self.value = value
+            self.exp_type=exp_type
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len | (self.exp_type <<9)))
+        packed.append(struct.pack("!L", OFDPA_EXPERIMETER))
+        #packed.append(struct.pack("!H", self.exp_type))
+        packed.append(struct.pack("!b", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = exp1ByteValue()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 0xffff0007)
+        experimenter = reader.read("!L")[0]
+        assert(experimenter == OFDPA_EXPERIMETER)
+        obj.exp_type= reader.read("!H")[0]
+        obj.value= reader.read("!b")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("exp1ByteValue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[0xffff0007] = exp1ByteValue
+
+class exp2ByteValue(oxm):
+    type_len = 0xffff0006
+
+    def __init__(self, exp_type=0, value=None):
+        if value != None:
+            self.value = value
+            self.exp_type=exp_type
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len | (self.exp_type <<9)))
+        packed.append(struct.pack("!L", OFDPA_EXPERIMETER))
+        #packed.append(struct.pack("!H", self.exp_type))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = exp2ByteValue()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 0xffff0008)
+        experimenter = reader.read("!L")[0]
+        assert(experimenter == OFDPA_EXPERIMETER)
+        obj.exp_type= reader.read("!H")[0]
+        obj.value= reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("exp2ByteValue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[0xffff0008] = exp2ByteValue
+
+class exp4ByteValue(oxm):
+    type_len = 0xffff0008
+
+    def __init__(self, exp_type=0, value=None, experimenter=OFDPA_EXPERIMETER):
+        if value != None:
+            self.value = value
+            self.exp_type=exp_type
+            self.experimenter = experimenter
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len | (self.exp_type <<9)))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = exp4ByteValue()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 0xffff000a)
+        experimenter = reader.read("!L")[0]
+        assert(experimenter == OFDPA_EXPERIMETER)
+        obj.exp_type= reader.read("!H")[0]
+        obj.value= reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("exp4ByteValue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[0xffff000a] = exp4ByteValue
+
+class exp4ByteReg( oxm ):
+    type_len = 0x80010000
+
+    def __init__( self, oxm_field=0 ):
+        self.oxm_field = oxm_field
+
+    def pack( self ):
+        packed = [ ]
+        packed.append( struct.pack( "!L", self.type_len | (self.oxm_field << 9) ) )
+        return ''.join( packed )
diff --git a/Fabric/Utilities/src/python/loxi/of13/util.py b/Fabric/Utilities/src/python/loxi/of13/util.py
new file mode 100644
index 0000000..fe23da1
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/util.py
@@ -0,0 +1,139 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+# Automatically generated by LOXI from template util.py
+# Do not modify
+
+import struct
+import loxi
+import const
+import common
+import action
+import instruction
+import oxm
+import action_id
+import instruction_id
+import meter_band
+
+def pretty_mac(mac):
+    return ':'.join(["%02x" % x for x in mac])
+
+def pretty_ipv4(v):
+    return "%d.%d.%d.%d" % ((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF)
+
+def pretty_flags(v, flag_names):
+    set_flags = []
+    for flag_name in flag_names:
+        flag_value = getattr(const, flag_name)
+        if v & flag_value == flag_value:
+            set_flags.append(flag_name)
+        elif v & flag_value:
+            set_flags.append('%s&%#x' % (flag_name, v & flag_value))
+        v &= ~flag_value
+    if v:
+        set_flags.append("%#x" % v)
+    return '|'.join(set_flags) or '0'
+
+
+def pretty_port(v):
+    named_ports = [(k,v2) for (k,v2) in const.__dict__.iteritems() if k.startswith('OFPP_')]
+    for (k, v2) in named_ports:
+        if v == v2:
+            return k
+    return v
+
+def pack_port_no(value):
+    return struct.pack("!L", value)
+
+def unpack_port_no(reader):
+    return reader.read("!L")[0]
+
+def pack_fm_cmd(value):
+    return struct.pack("!B", value)
+
+def unpack_fm_cmd(reader):
+    return reader.read("!B")[0]
+
+def init_wc_bmap():
+    return 0
+
+def pack_wc_bmap(value):
+    return struct.pack("!Q", value)
+
+def unpack_wc_bmap(reader):
+    return reader.read("!Q")[0]
+
+def init_match_bmap():
+    return 0
+
+def pack_match_bmap(value):
+    return struct.pack("!Q", value)
+
+def unpack_match_bmap(reader):
+    return reader.read("!Q")[0]
+
+MASK64 = (1 << 64) - 1
+
+def pack_bitmap_128(value):
+    x = 0l
+    for y in value:
+        x |= 1 << y
+    return struct.pack("!QQ", (x >> 64) & MASK64, x & MASK64)
+
+def unpack_bitmap_128(reader):
+    hi, lo = reader.read("!QQ")
+    x = (hi << 64) | lo
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_bitmap_512(value):
+    words = [0] * 8
+    for v in value:
+        assert v < 512
+        words[7-v/64] |= 1 << (v % 64)
+    return struct.pack("!8Q", *words)
+
+def unpack_bitmap_512(reader):
+    words = reader.read("!8Q")
+    x = 0l
+    for word in words:
+        x <<= 64
+        x |= word
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_checksum_128(value):
+    return struct.pack("!QQ", (value >> 64) & MASK64, value & MASK64)
+
+def unpack_checksum_128(reader):
+    hi, lo = reader.read("!QQ")
+    return (hi << 64) | lo
diff --git a/Fabric/Utilities/src/python/loxi/of14/__init__.py b/Fabric/Utilities/src/python/loxi/of14/__init__.py
new file mode 100644
index 0000000..a8105d6
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/__init__.py
@@ -0,0 +1,46 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template init.py
+# Do not modify
+
+import const
+import port_desc_prop
+import bsn_tlv
+import meter_band
+import table_mod_prop
+import instruction
+import queue_desc_prop
+import oxm
+import bundle_prop
+import common
+import instruction_id
+import action
+import role_prop
+import message
+import queue_stats_prop
+import port_stats_prop
+import port_mod_prop
+import async_config_prop
+import action_id
+from const import *
+from common import *
+from loxi import ProtocolError
diff --git a/Fabric/Utilities/src/python/loxi/of14/action.py b/Fabric/Utilities/src/python/loxi/of14/action.py
new file mode 100644
index 0000000..93dd3dc
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/action.py
@@ -0,0 +1,1301 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class action(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = action.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = action()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("action {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(action):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed.append(loxi.generic_util.pad_to(8, length))
+        length += len(packed[-1])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_checksum(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_checksum_128(self.checksum))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_checksum()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_checksum {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_checksum
+
+class bsn_gentable(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, table_id=None, key=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.table_id))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.table_id = reader.read("!L")[0]
+        obj.key = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.key != other.key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_gentable
+
+class bsn_mirror(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, dest_port=None, vlan_tag=None, copy_stage=None):
+        if dest_port != None:
+            self.dest_port = dest_port
+        else:
+            self.dest_port = 0
+        if vlan_tag != None:
+            self.vlan_tag = vlan_tag
+        else:
+            self.vlan_tag = 0
+        if copy_stage != None:
+            self.copy_stage = copy_stage
+        else:
+            self.copy_stage = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dest_port))
+        packed.append(struct.pack("!L", self.vlan_tag))
+        packed.append(struct.pack("!B", self.copy_stage))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_mirror()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.dest_port = reader.read("!L")[0]
+        obj.vlan_tag = reader.read("!L")[0]
+        obj.copy_stage = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dest_port != other.dest_port: return False
+        if self.vlan_tag != other.vlan_tag: return False
+        if self.copy_stage != other.copy_stage: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_mirror {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dest_port = ");
+                q.text("%#x" % self.dest_port)
+                q.text(","); q.breakable()
+                q.text("vlan_tag = ");
+                q.text("%#x" % self.vlan_tag)
+                q.text(","); q.breakable()
+                q.text("copy_stage = ");
+                q.text("%#x" % self.copy_stage)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_mirror
+
+class bsn_set_tunnel_dst(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, dst=None):
+        if dst != None:
+            self.dst = dst
+        else:
+            self.dst = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dst))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_tunnel_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.dst = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dst != other.dst: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_tunnel_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dst = ");
+                q.text("%#x" % self.dst)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_set_tunnel_dst
+
+class copy_ttl_in(action):
+    type = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_in()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[12] = copy_ttl_in
+
+class copy_ttl_out(action):
+    type = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_out()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[11] = copy_ttl_out
+
+class dec_mpls_ttl(action):
+    type = 16
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[16] = dec_mpls_ttl
+
+class dec_nw_ttl(action):
+    type = 24
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[24] = dec_nw_ttl
+
+class group(action):
+    type = 22
+
+    def __init__(self, group_id=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.group_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.group_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[22] = group
+
+class nicira(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 8992
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = nicira.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!H")[0]
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira
+
+class nicira_dec_ttl(nicira):
+    type = 65535
+    experimenter = 8992
+    subtype = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_dec_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == 18)
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_dec_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+nicira.subtypes[18] = nicira_dec_ttl
+
+class output(action):
+    type = 0
+
+    def __init__(self, port=None, max_len=None):
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if max_len != None:
+            self.max_len = max_len
+        else:
+            self.max_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", self.max_len))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = output()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.port = util.unpack_port_no(reader)
+        obj.max_len = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port != other.port: return False
+        if self.max_len != other.max_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("max_len = ");
+                q.text("%#x" % self.max_len)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[0] = output
+
+class pop_mpls(action):
+    type = 20
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[20] = pop_mpls
+
+class pop_pbb(action):
+    type = 27
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 27)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[27] = pop_pbb
+
+class pop_vlan(action):
+    type = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[18] = pop_vlan
+
+class push_mpls(action):
+    type = 19
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[19] = push_mpls
+
+class push_pbb(action):
+    type = 26
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 26)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[26] = push_pbb
+
+class push_vlan(action):
+    type = 17
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[17] = push_vlan
+
+class set_field(action):
+    type = 25
+
+    def __init__(self, field=None):
+        if field != None:
+            self.field = field
+        else:
+            self.field = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(self.field.pack())
+        length = sum([len(x) for x in packed])
+        packed.append(loxi.generic_util.pad_to(8, length))
+        length += len(packed[-1])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_field()
+        _type = reader.read("!H")[0]
+        assert(_type == 25)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.field = ofp.oxm.oxm.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.field != other.field: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_field {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("field = ");
+                q.pp(self.field)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[25] = set_field
+
+class set_mpls_ttl(action):
+    type = 15
+
+    def __init__(self, mpls_ttl=None):
+        if mpls_ttl != None:
+            self.mpls_ttl = mpls_ttl
+        else:
+            self.mpls_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.mpls_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.mpls_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mpls_ttl != other.mpls_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mpls_ttl = ");
+                q.text("%#x" % self.mpls_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[15] = set_mpls_ttl
+
+class set_nw_ttl(action):
+    type = 23
+
+    def __init__(self, nw_ttl=None):
+        if nw_ttl != None:
+            self.nw_ttl = nw_ttl
+        else:
+            self.nw_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.nw_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_ttl != other.nw_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_ttl = ");
+                q.text("%#x" % self.nw_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[23] = set_nw_ttl
+
+class set_queue(action):
+    type = 21
+
+    def __init__(self, queue_id=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_queue()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[21] = set_queue
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/action_id.py b/Fabric/Utilities/src/python/loxi/of14/action_id.py
new file mode 100644
index 0000000..ee33666
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/action_id.py
@@ -0,0 +1,1082 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class action_id(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = action_id.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = action_id()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("action_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(action_id):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_checksum(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_checksum()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_checksum {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_checksum
+
+class bsn_gentable(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_gentable
+
+class bsn_mirror(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_mirror()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_mirror {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_mirror
+
+class bsn_set_tunnel_dst(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_tunnel_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_tunnel_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_set_tunnel_dst
+
+class copy_ttl_in(action_id):
+    type = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_in()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[12] = copy_ttl_in
+
+class copy_ttl_out(action_id):
+    type = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_out()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[11] = copy_ttl_out
+
+class dec_mpls_ttl(action_id):
+    type = 16
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[16] = dec_mpls_ttl
+
+class dec_nw_ttl(action_id):
+    type = 24
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[24] = dec_nw_ttl
+
+class group(action_id):
+    type = 22
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[22] = group
+
+class nicira(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 8992
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = nicira.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira
+
+class nicira_dec_ttl(nicira):
+    type = 65535
+    experimenter = 8992
+    subtype = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_dec_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == 18)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_dec_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+nicira.subtypes[18] = nicira_dec_ttl
+
+class output(action_id):
+    type = 0
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = output()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[0] = output
+
+class pop_mpls(action_id):
+    type = 20
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[20] = pop_mpls
+
+class pop_pbb(action_id):
+    type = 27
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 27)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[27] = pop_pbb
+
+class pop_vlan(action_id):
+    type = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[18] = pop_vlan
+
+class push_mpls(action_id):
+    type = 19
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[19] = push_mpls
+
+class push_pbb(action_id):
+    type = 26
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 26)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[26] = push_pbb
+
+class push_vlan(action_id):
+    type = 17
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[17] = push_vlan
+
+class set_field(action_id):
+    type = 25
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_field()
+        _type = reader.read("!H")[0]
+        assert(_type == 25)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_field {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[25] = set_field
+
+class set_mpls_ttl(action_id):
+    type = 15
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[15] = set_mpls_ttl
+
+class set_nw_ttl(action_id):
+    type = 23
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[23] = set_nw_ttl
+
+class set_queue(action_id):
+    type = 21
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_queue()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[21] = set_queue
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/async_config_prop.py b/Fabric/Utilities/src/python/loxi/of14/async_config_prop.py
new file mode 100644
index 0000000..f3539da
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/async_config_prop.py
@@ -0,0 +1,720 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class async_config_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = async_config_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = async_config_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_config_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter_master(async_config_prop):
+    type = 65535
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = experimenter_master()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_master {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[65535] = experimenter_master
+
+class experimenter_slave(async_config_prop):
+    type = 65534
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = experimenter_slave()
+        _type = reader.read("!H")[0]
+        assert(_type == 65534)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_slave {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[65534] = experimenter_slave
+
+class flow_removed_master(async_config_prop):
+    type = 5
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_removed_master()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_removed_master {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[5] = flow_removed_master
+
+class flow_removed_slave(async_config_prop):
+    type = 4
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_removed_slave()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_removed_slave {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[4] = flow_removed_slave
+
+class packet_in_master(async_config_prop):
+    type = 1
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_in_master()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_in_master {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[1] = packet_in_master
+
+class packet_in_slave(async_config_prop):
+    type = 0
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_in_slave()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_in_slave {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[0] = packet_in_slave
+
+class port_status_master(async_config_prop):
+    type = 3
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_status_master()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_status_master {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[3] = port_status_master
+
+class port_status_slave(async_config_prop):
+    type = 2
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_status_slave()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_status_slave {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[2] = port_status_slave
+
+class requestforward_master(async_config_prop):
+    type = 11
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = requestforward_master()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("requestforward_master {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[11] = requestforward_master
+
+class requestforward_slave(async_config_prop):
+    type = 10
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = requestforward_slave()
+        _type = reader.read("!H")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("requestforward_slave {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[10] = requestforward_slave
+
+class role_status_master(async_config_prop):
+    type = 7
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_status_master()
+        _type = reader.read("!H")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_status_master {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[7] = role_status_master
+
+class role_status_slave(async_config_prop):
+    type = 6
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_status_slave()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_status_slave {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[6] = role_status_slave
+
+class table_status_master(async_config_prop):
+    type = 9
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_status_master()
+        _type = reader.read("!H")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_status_master {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[9] = table_status_master
+
+class table_status_slave(async_config_prop):
+    type = 8
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_status_slave()
+        _type = reader.read("!H")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_status_slave {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[8] = table_status_slave
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/bsn_tlv.py b/Fabric/Utilities/src/python/loxi/of14/bsn_tlv.py
new file mode 100644
index 0000000..b61c6d4
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/bsn_tlv.py
@@ -0,0 +1,3881 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class bsn_tlv(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bsn_tlv.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_tlv()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tlv {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class actor_key(bsn_tlv):
+    type = 44
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_key()
+        _type = reader.read("!H")[0]
+        assert(_type == 44)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_key {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[44] = actor_key
+
+class actor_port_num(bsn_tlv):
+    type = 43
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_port_num()
+        _type = reader.read("!H")[0]
+        assert(_type == 43)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_port_num {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[43] = actor_port_num
+
+class actor_port_priority(bsn_tlv):
+    type = 42
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_port_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 42)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_port_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[42] = actor_port_priority
+
+class actor_state(bsn_tlv):
+    type = 53
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_state()
+        _type = reader.read("!H")[0]
+        assert(_type == 53)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_state {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[53] = actor_state
+
+class actor_system_mac(bsn_tlv):
+    type = 41
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_system_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 41)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_system_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[41] = actor_system_mac
+
+class actor_system_priority(bsn_tlv):
+    type = 40
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_system_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 40)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_system_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[40] = actor_system_priority
+
+class anchor(bsn_tlv):
+    type = 81
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = anchor()
+        _type = reader.read("!H")[0]
+        assert(_type == 81)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("anchor {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[81] = anchor
+
+class broadcast_query_timeout(bsn_tlv):
+    type = 10
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = broadcast_query_timeout()
+        _type = reader.read("!H")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("broadcast_query_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[10] = broadcast_query_timeout
+
+class bucket(bsn_tlv):
+    type = 64
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket()
+        _type = reader.read("!H")[0]
+        assert(_type == 64)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[64] = bucket
+
+class circuit_id(bsn_tlv):
+    type = 14
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(self.value)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = circuit_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("circuit_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[14] = circuit_id
+
+class convergence_status(bsn_tlv):
+    type = 45
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = convergence_status()
+        _type = reader.read("!H")[0]
+        assert(_type == 45)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("convergence_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[45] = convergence_status
+
+class crc_enabled(bsn_tlv):
+    type = 22
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = crc_enabled()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("crc_enabled {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[22] = crc_enabled
+
+class data(bsn_tlv):
+    type = 55
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(self.value)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = data()
+        _type = reader.read("!H")[0]
+        assert(_type == 55)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("data {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[55] = data
+
+class eth_dst(bsn_tlv):
+    type = 33
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 33)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[33] = eth_dst
+
+class eth_src(bsn_tlv):
+    type = 32
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 32)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[32] = eth_src
+
+class external_gateway_ip(bsn_tlv):
+    type = 26
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_gateway_ip()
+        _type = reader.read("!H")[0]
+        assert(_type == 26)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_gateway_ip {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[26] = external_gateway_ip
+
+class external_gateway_mac(bsn_tlv):
+    type = 29
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_gateway_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 29)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_gateway_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[29] = external_gateway_mac
+
+class external_ip(bsn_tlv):
+    type = 23
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_ip()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_ip {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[23] = external_ip
+
+class external_mac(bsn_tlv):
+    type = 24
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[24] = external_mac
+
+class external_netmask(bsn_tlv):
+    type = 25
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_netmask()
+        _type = reader.read("!H")[0]
+        assert(_type == 25)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_netmask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[25] = external_netmask
+
+class generation_id(bsn_tlv):
+    type = 80
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = generation_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 80)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("generation_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[80] = generation_id
+
+class header_size(bsn_tlv):
+    type = 31
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = header_size()
+        _type = reader.read("!H")[0]
+        assert(_type == 31)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("header_size {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[31] = header_size
+
+class icmp_code(bsn_tlv):
+    type = 69
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmp_code()
+        _type = reader.read("!H")[0]
+        assert(_type == 69)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmp_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[69] = icmp_code
+
+class icmp_id(bsn_tlv):
+    type = 70
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmp_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 70)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmp_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[70] = icmp_id
+
+class icmp_type(bsn_tlv):
+    type = 68
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmp_type()
+        _type = reader.read("!H")[0]
+        assert(_type == 68)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmp_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[68] = icmp_type
+
+class idle_notification(bsn_tlv):
+    type = 7
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = idle_notification()
+        _type = reader.read("!H")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("idle_notification {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[7] = idle_notification
+
+class idle_time(bsn_tlv):
+    type = 5
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = idle_time()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("idle_time {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[5] = idle_time
+
+class idle_timeout(bsn_tlv):
+    type = 8
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = idle_timeout()
+        _type = reader.read("!H")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("idle_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[8] = idle_timeout
+
+class igmp_snooping(bsn_tlv):
+    type = 78
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = igmp_snooping()
+        _type = reader.read("!H")[0]
+        assert(_type == 78)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("igmp_snooping {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[78] = igmp_snooping
+
+class internal_gateway_mac(bsn_tlv):
+    type = 28
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = internal_gateway_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 28)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("internal_gateway_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[28] = internal_gateway_mac
+
+class internal_mac(bsn_tlv):
+    type = 27
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = internal_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 27)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("internal_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[27] = internal_mac
+
+class interval(bsn_tlv):
+    type = 58
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = interval()
+        _type = reader.read("!H")[0]
+        assert(_type == 58)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("interval {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[58] = interval
+
+class ip_proto(bsn_tlv):
+    type = 67
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto()
+        _type = reader.read("!H")[0]
+        assert(_type == 67)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[67] = ip_proto
+
+class ipv4(bsn_tlv):
+    type = 4
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[4] = ipv4
+
+class ipv4_dst(bsn_tlv):
+    type = 35
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 35)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[35] = ipv4_dst
+
+class ipv4_netmask(bsn_tlv):
+    type = 60
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_netmask()
+        _type = reader.read("!H")[0]
+        assert(_type == 60)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_netmask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[60] = ipv4_netmask
+
+class ipv4_src(bsn_tlv):
+    type = 34
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 34)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[34] = ipv4_src
+
+class l2_multicast_lookup(bsn_tlv):
+    type = 79
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = l2_multicast_lookup()
+        _type = reader.read("!H")[0]
+        assert(_type == 79)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("l2_multicast_lookup {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[79] = l2_multicast_lookup
+
+class mac(bsn_tlv):
+    type = 1
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[1] = mac
+
+class mac_mask(bsn_tlv):
+    type = 56
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mac_mask()
+        _type = reader.read("!H")[0]
+        assert(_type == 56)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mac_mask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[56] = mac_mask
+
+class miss_packets(bsn_tlv):
+    type = 13
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = miss_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("miss_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[13] = miss_packets
+
+class mpls_control_word(bsn_tlv):
+    type = 62
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_control_word()
+        _type = reader.read("!H")[0]
+        assert(_type == 62)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_control_word {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[62] = mpls_control_word
+
+class mpls_label(bsn_tlv):
+    type = 61
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label()
+        _type = reader.read("!H")[0]
+        assert(_type == 61)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[61] = mpls_label
+
+class mpls_sequenced(bsn_tlv):
+    type = 63
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_sequenced()
+        _type = reader.read("!H")[0]
+        assert(_type == 63)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_sequenced {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[63] = mpls_sequenced
+
+class name(bsn_tlv):
+    type = 52
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(self.value)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = name()
+        _type = reader.read("!H")[0]
+        assert(_type == 52)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("name {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[52] = name
+
+class offset(bsn_tlv):
+    type = 82
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = offset()
+        _type = reader.read("!H")[0]
+        assert(_type == 82)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("offset {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[82] = offset
+
+class partner_key(bsn_tlv):
+    type = 51
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_key()
+        _type = reader.read("!H")[0]
+        assert(_type == 51)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_key {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[51] = partner_key
+
+class partner_port_num(bsn_tlv):
+    type = 50
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_port_num()
+        _type = reader.read("!H")[0]
+        assert(_type == 50)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_port_num {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[50] = partner_port_num
+
+class partner_port_priority(bsn_tlv):
+    type = 49
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_port_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 49)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_port_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[49] = partner_port_priority
+
+class partner_state(bsn_tlv):
+    type = 54
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_state()
+        _type = reader.read("!H")[0]
+        assert(_type == 54)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_state {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[54] = partner_state
+
+class partner_system_mac(bsn_tlv):
+    type = 48
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_system_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 48)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_system_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[48] = partner_system_mac
+
+class partner_system_priority(bsn_tlv):
+    type = 47
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_system_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 47)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_system_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[47] = partner_system_priority
+
+class port(bsn_tlv):
+    type = 0
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(util.pack_port_no(self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[0] = port
+
+class priority(bsn_tlv):
+    type = 57
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 57)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[57] = priority
+
+class queue_id(bsn_tlv):
+    type = 20
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[20] = queue_id
+
+class queue_weight(bsn_tlv):
+    type = 21
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_weight()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_weight {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[21] = queue_weight
+
+class reference(bsn_tlv):
+    type = 59
+
+    def __init__(self, table_id=None, key=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = reference()
+        _type = reader.read("!H")[0]
+        assert(_type == 59)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.table_id = reader.read("!H")[0]
+        obj.key = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.key != other.key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("reference {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[59] = reference
+
+class reply_packets(bsn_tlv):
+    type = 12
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = reply_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("reply_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[12] = reply_packets
+
+class request_packets(bsn_tlv):
+    type = 11
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = request_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("request_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[11] = request_packets
+
+class rx_bytes(bsn_tlv):
+    type = 71
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = rx_bytes()
+        _type = reader.read("!H")[0]
+        assert(_type == 71)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("rx_bytes {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[71] = rx_bytes
+
+class rx_packets(bsn_tlv):
+    type = 2
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = rx_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("rx_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[2] = rx_packets
+
+class sampling_rate(bsn_tlv):
+    type = 30
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sampling_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 30)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sampling_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[30] = sampling_rate
+
+class set_loopback_mode(bsn_tlv):
+    type = 74
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_loopback_mode()
+        _type = reader.read("!H")[0]
+        assert(_type == 74)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_loopback_mode {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[74] = set_loopback_mode
+
+class strip_mpls_l2_on_ingress(bsn_tlv):
+    type = 75
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = strip_mpls_l2_on_ingress()
+        _type = reader.read("!H")[0]
+        assert(_type == 75)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("strip_mpls_l2_on_ingress {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[75] = strip_mpls_l2_on_ingress
+
+class strip_mpls_l3_on_ingress(bsn_tlv):
+    type = 76
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = strip_mpls_l3_on_ingress()
+        _type = reader.read("!H")[0]
+        assert(_type == 76)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("strip_mpls_l3_on_ingress {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[76] = strip_mpls_l3_on_ingress
+
+class strip_vlan_on_egress(bsn_tlv):
+    type = 73
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = strip_vlan_on_egress()
+        _type = reader.read("!H")[0]
+        assert(_type == 73)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("strip_vlan_on_egress {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[73] = strip_vlan_on_egress
+
+class sub_agent_id(bsn_tlv):
+    type = 38
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sub_agent_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 38)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sub_agent_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[38] = sub_agent_id
+
+class tcp_dst(bsn_tlv):
+    type = 66
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 66)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[66] = tcp_dst
+
+class tcp_src(bsn_tlv):
+    type = 65
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 65)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[65] = tcp_src
+
+class tx_bytes(bsn_tlv):
+    type = 39
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tx_bytes()
+        _type = reader.read("!H")[0]
+        assert(_type == 39)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tx_bytes {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[39] = tx_bytes
+
+class tx_packets(bsn_tlv):
+    type = 3
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tx_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tx_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[3] = tx_packets
+
+class udf_anchor(bsn_tlv):
+    type = 16
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_anchor()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_anchor {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[16] = udf_anchor
+
+class udf_id(bsn_tlv):
+    type = 15
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[15] = udf_id
+
+class udf_length(bsn_tlv):
+    type = 18
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_length()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_length {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[18] = udf_length
+
+class udf_offset(bsn_tlv):
+    type = 17
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_offset()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_offset {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[17] = udf_offset
+
+class udp_dst(bsn_tlv):
+    type = 37
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 37)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[37] = udp_dst
+
+class udp_src(bsn_tlv):
+    type = 36
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 36)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[36] = udp_src
+
+class unicast_query_timeout(bsn_tlv):
+    type = 9
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = unicast_query_timeout()
+        _type = reader.read("!H")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("unicast_query_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[9] = unicast_query_timeout
+
+class vlan_pcp(bsn_tlv):
+    type = 72
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp()
+        _type = reader.read("!H")[0]
+        assert(_type == 72)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[72] = vlan_pcp
+
+class vlan_vid(bsn_tlv):
+    type = 6
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[6] = vlan_vid
+
+class vlan_vid_mask(bsn_tlv):
+    type = 77
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid_mask()
+        _type = reader.read("!H")[0]
+        assert(_type == 77)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid_mask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[77] = vlan_vid_mask
+
+class vrf(bsn_tlv):
+    type = 19
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vrf()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vrf {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[19] = vrf
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/bundle_prop.py b/Fabric/Utilities/src/python/loxi/of14/bundle_prop.py
new file mode 100644
index 0000000..61ad92f
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/bundle_prop.py
@@ -0,0 +1,141 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class bundle_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bundle_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bundle_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bundle_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(bundle_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, exp_type=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.exp_type = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("exp_type = ");
+                q.text("%#x" % self.exp_type)
+            q.breakable()
+        q.text('}')
+
+bundle_prop.subtypes[65535] = experimenter
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/common.py b/Fabric/Utilities/src/python/loxi/of14/common.py
new file mode 100644
index 0000000..76098fc
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/common.py
@@ -0,0 +1,4333 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class bsn_controller_connection(loxi.OFObject):
+
+    def __init__(self, state=None, auxiliary_id=None, role=None, uri=None):
+        if state != None:
+            self.state = state
+        else:
+            self.state = 0
+        if auxiliary_id != None:
+            self.auxiliary_id = auxiliary_id
+        else:
+            self.auxiliary_id = 0
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if uri != None:
+            self.uri = uri
+        else:
+            self.uri = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.state))
+        packed.append(struct.pack("!B", self.auxiliary_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.role))
+        packed.append(struct.pack("!256s", self.uri))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_controller_connection()
+        obj.state = reader.read("!B")[0]
+        obj.auxiliary_id = reader.read("!B")[0]
+        reader.skip(2)
+        obj.role = reader.read("!L")[0]
+        obj.uri = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.state != other.state: return False
+        if self.auxiliary_id != other.auxiliary_id: return False
+        if self.role != other.role: return False
+        if self.uri != other.uri: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_controller_connection {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("state = ");
+                q.text("%#x" % self.state)
+                q.text(","); q.breakable()
+                q.text("auxiliary_id = ");
+                q.text("%#x" % self.auxiliary_id)
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("uri = ");
+                q.pp(self.uri)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_debug_counter_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, counter_id=None, name=None, description=None):
+        if counter_id != None:
+            self.counter_id = counter_id
+        else:
+            self.counter_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if description != None:
+            self.description = description
+        else:
+            self.description = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.counter_id))
+        packed.append(struct.pack("!64s", self.name))
+        packed.append(struct.pack("!256s", self.description))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_desc_stats_entry()
+        obj.counter_id = reader.read("!Q")[0]
+        obj.name = reader.read("!64s")[0].rstrip("\x00")
+        obj.description = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.counter_id != other.counter_id: return False
+        if self.name != other.name: return False
+        if self.description != other.description: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("counter_id = ");
+                q.text("%#x" % self.counter_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("description = ");
+                q.pp(self.description)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_debug_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, counter_id=None, value=None):
+        if counter_id != None:
+            self.counter_id = counter_id
+        else:
+            self.counter_id = 0
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.counter_id))
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_stats_entry()
+        obj.counter_id = reader.read("!Q")[0]
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.counter_id != other.counter_id: return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("counter_id = ");
+                q.text("%#x" % self.counter_id)
+                q.text(","); q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_flow_checksum_bucket_stats_entry(loxi.OFObject):
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_checksum_bucket_stats_entry()
+        obj.checksum = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_checksum_bucket_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.text("%#x" % self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_generic_stats_entry(loxi.OFObject):
+
+    def __init__(self, tlvs=None):
+        if tlvs != None:
+            self.tlvs = tlvs
+        else:
+            self.tlvs = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(loxi.generic_util.pack_list(self.tlvs))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generic_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.tlvs = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.tlvs != other.tlvs: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generic_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("tlvs = ");
+                q.pp(self.tlvs)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_bucket_stats_entry(loxi.OFObject):
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_checksum_128(self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_bucket_stats_entry()
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_bucket_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, name=None, buckets_size=None, max_entries=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if buckets_size != None:
+            self.buckets_size = buckets_size
+        else:
+            self.buckets_size = 0
+        if max_entries != None:
+            self.max_entries = max_entries
+        else:
+            self.max_entries = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(struct.pack("!32s", self.name))
+        packed.append(struct.pack("!L", self.buckets_size))
+        packed.append(struct.pack("!L", self.max_entries))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!H")[0]
+        obj.name = reader.read("!32s")[0].rstrip("\x00")
+        obj.buckets_size = reader.read("!L")[0]
+        obj.max_entries = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.name != other.name: return False
+        if self.buckets_size != other.buckets_size: return False
+        if self.max_entries != other.max_entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("buckets_size = ");
+                q.text("%#x" % self.buckets_size)
+                q.text(","); q.breakable()
+                q.text("max_entries = ");
+                q.text("%#x" % self.max_entries)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_entry_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, checksum=None, key=None, value=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        if value != None:
+            self.value = value
+        else:
+            self.value = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", 0)) # placeholder for key_length at index 1
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        packed[1] = struct.pack("!H", len(packed[-1]))
+        packed.append(loxi.generic_util.pack_list(self.value))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        _key_length = reader.read("!H")[0]
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.key = loxi.generic_util.unpack_list(reader.slice(_key_length), ofp.bsn_tlv.bsn_tlv.unpack)
+        obj.value = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        if self.key != other.key: return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+                q.text(","); q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_entry_stats_entry(loxi.OFObject):
+
+    def __init__(self, key=None, stats=None):
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        if stats != None:
+            self.stats = stats
+        else:
+            self.stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", 0)) # placeholder for key_length at index 1
+        packed.append(loxi.generic_util.pack_list(self.key))
+        packed[1] = struct.pack("!H", len(packed[-1]))
+        packed.append(loxi.generic_util.pack_list(self.stats))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        _key_length = reader.read("!H")[0]
+        obj.key = loxi.generic_util.unpack_list(reader.slice(_key_length), ofp.bsn_tlv.bsn_tlv.unpack)
+        obj.stats = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.key != other.key: return False
+        if self.stats != other.stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+                q.text(","); q.breakable()
+                q.text("stats = ");
+                q.pp(self.stats)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, entry_count=None, checksum=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if entry_count != None:
+            self.entry_count = entry_count
+        else:
+            self.entry_count = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.entry_count))
+        packed.append(util.pack_checksum_128(self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_stats_entry()
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.entry_count = reader.read("!L")[0]
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.entry_count != other.entry_count: return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("entry_count = ");
+                q.text("%#x" % self.entry_count)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_interface(loxi.OFObject):
+
+    def __init__(self, hw_addr=None, name=None, ipv4_addr=None, ipv4_netmask=None):
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if ipv4_addr != None:
+            self.ipv4_addr = ipv4_addr
+        else:
+            self.ipv4_addr = 0
+        if ipv4_netmask != None:
+            self.ipv4_netmask = ipv4_netmask
+        else:
+            self.ipv4_netmask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.ipv4_addr))
+        packed.append(struct.pack("!L", self.ipv4_netmask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_interface()
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.ipv4_addr = reader.read("!L")[0]
+        obj.ipv4_netmask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.ipv4_addr != other.ipv4_addr: return False
+        if self.ipv4_netmask != other.ipv4_netmask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_interface {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("ipv4_addr = ");
+                q.text(util.pretty_ipv4(self.ipv4_addr))
+                q.text(","); q.breakable()
+                q.text("ipv4_netmask = ");
+                q.text(util.pretty_ipv4(self.ipv4_netmask))
+            q.breakable()
+        q.text('}')
+
+
+class bsn_lacp_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, actor_sys_priority=None, actor_sys_mac=None, actor_port_priority=None, actor_port_num=None, actor_key=None, convergence_status=None, partner_sys_priority=None, partner_sys_mac=None, partner_port_priority=None, partner_port_num=None, partner_key=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if actor_sys_priority != None:
+            self.actor_sys_priority = actor_sys_priority
+        else:
+            self.actor_sys_priority = 0
+        if actor_sys_mac != None:
+            self.actor_sys_mac = actor_sys_mac
+        else:
+            self.actor_sys_mac = [0,0,0,0,0,0]
+        if actor_port_priority != None:
+            self.actor_port_priority = actor_port_priority
+        else:
+            self.actor_port_priority = 0
+        if actor_port_num != None:
+            self.actor_port_num = actor_port_num
+        else:
+            self.actor_port_num = 0
+        if actor_key != None:
+            self.actor_key = actor_key
+        else:
+            self.actor_key = 0
+        if convergence_status != None:
+            self.convergence_status = convergence_status
+        else:
+            self.convergence_status = 0
+        if partner_sys_priority != None:
+            self.partner_sys_priority = partner_sys_priority
+        else:
+            self.partner_sys_priority = 0
+        if partner_sys_mac != None:
+            self.partner_sys_mac = partner_sys_mac
+        else:
+            self.partner_sys_mac = [0,0,0,0,0,0]
+        if partner_port_priority != None:
+            self.partner_port_priority = partner_port_priority
+        else:
+            self.partner_port_priority = 0
+        if partner_port_num != None:
+            self.partner_port_num = partner_port_num
+        else:
+            self.partner_port_num = 0
+        if partner_key != None:
+            self.partner_key = partner_key
+        else:
+            self.partner_key = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!H", self.actor_sys_priority))
+        packed.append(struct.pack("!6B", *self.actor_sys_mac))
+        packed.append(struct.pack("!H", self.actor_port_priority))
+        packed.append(struct.pack("!H", self.actor_port_num))
+        packed.append(struct.pack("!H", self.actor_key))
+        packed.append(struct.pack("!B", self.convergence_status))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.partner_sys_priority))
+        packed.append(struct.pack("!6B", *self.partner_sys_mac))
+        packed.append(struct.pack("!H", self.partner_port_priority))
+        packed.append(struct.pack("!H", self.partner_port_num))
+        packed.append(struct.pack("!H", self.partner_key))
+        packed.append('\x00' * 2)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        obj.actor_sys_priority = reader.read("!H")[0]
+        obj.actor_sys_mac = list(reader.read('!6B'))
+        obj.actor_port_priority = reader.read("!H")[0]
+        obj.actor_port_num = reader.read("!H")[0]
+        obj.actor_key = reader.read("!H")[0]
+        obj.convergence_status = reader.read("!B")[0]
+        reader.skip(1)
+        obj.partner_sys_priority = reader.read("!H")[0]
+        obj.partner_sys_mac = list(reader.read('!6B'))
+        obj.partner_port_priority = reader.read("!H")[0]
+        obj.partner_port_num = reader.read("!H")[0]
+        obj.partner_key = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.actor_sys_priority != other.actor_sys_priority: return False
+        if self.actor_sys_mac != other.actor_sys_mac: return False
+        if self.actor_port_priority != other.actor_port_priority: return False
+        if self.actor_port_num != other.actor_port_num: return False
+        if self.actor_key != other.actor_key: return False
+        if self.convergence_status != other.convergence_status: return False
+        if self.partner_sys_priority != other.partner_sys_priority: return False
+        if self.partner_sys_mac != other.partner_sys_mac: return False
+        if self.partner_port_priority != other.partner_port_priority: return False
+        if self.partner_port_num != other.partner_port_num: return False
+        if self.partner_key != other.partner_key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("actor_sys_priority = ");
+                q.text("%#x" % self.actor_sys_priority)
+                q.text(","); q.breakable()
+                q.text("actor_sys_mac = ");
+                q.text(util.pretty_mac(self.actor_sys_mac))
+                q.text(","); q.breakable()
+                q.text("actor_port_priority = ");
+                q.text("%#x" % self.actor_port_priority)
+                q.text(","); q.breakable()
+                q.text("actor_port_num = ");
+                q.text("%#x" % self.actor_port_num)
+                q.text(","); q.breakable()
+                q.text("actor_key = ");
+                q.text("%#x" % self.actor_key)
+                q.text(","); q.breakable()
+                q.text("convergence_status = ");
+                q.text("%#x" % self.convergence_status)
+                q.text(","); q.breakable()
+                q.text("partner_sys_priority = ");
+                q.text("%#x" % self.partner_sys_priority)
+                q.text(","); q.breakable()
+                q.text("partner_sys_mac = ");
+                q.text(util.pretty_mac(self.partner_sys_mac))
+                q.text(","); q.breakable()
+                q.text("partner_port_priority = ");
+                q.text("%#x" % self.partner_port_priority)
+                q.text(","); q.breakable()
+                q.text("partner_port_num = ");
+                q.text("%#x" % self.partner_port_num)
+                q.text(","); q.breakable()
+                q.text("partner_key = ");
+                q.text("%#x" % self.partner_key)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_port_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, values=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if values != None:
+            self.values = values
+        else:
+            self.values = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(loxi.generic_util.pack_list(self.values))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_port_counter_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.values = loxi.generic_util.unpack_list(reader, ofp.common.uint64.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.values != other.values: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_port_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("values = ");
+                q.pp(self.values)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_switch_pipeline_stats_entry(loxi.OFObject):
+
+    def __init__(self, pipeline=None):
+        if pipeline != None:
+            self.pipeline = pipeline
+        else:
+            self.pipeline = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!256s", self.pipeline))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_switch_pipeline_stats_entry()
+        obj.pipeline = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.pipeline != other.pipeline: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_switch_pipeline_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("pipeline = ");
+                q.pp(self.pipeline)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_table_checksum_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, checksum=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!Q", self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_checksum_stats_entry()
+        obj.table_id = reader.read("!B")[0]
+        obj.checksum = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_checksum_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.text("%#x" % self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bsn_vport.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_vport()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vlan_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, vlan_vid=None, values=None):
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        if values != None:
+            self.values = values
+        else:
+            self.values = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.values))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_counter_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.vlan_vid = reader.read("!H")[0]
+        reader.skip(4)
+        obj.values = loxi.generic_util.unpack_list(reader, ofp.common.uint64.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vlan_vid != other.vlan_vid: return False
+        if self.values != other.values: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+                q.text(","); q.breakable()
+                q.text("values = ");
+                q.pp(self.values)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport_l2gre(bsn_vport):
+    type = 1
+
+    def __init__(self, flags=None, port_no=None, loopback_port_no=None, local_mac=None, nh_mac=None, src_ip=None, dst_ip=None, dscp=None, ttl=None, vpn=None, rate_limit=None, if_name=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if loopback_port_no != None:
+            self.loopback_port_no = loopback_port_no
+        else:
+            self.loopback_port_no = 0
+        if local_mac != None:
+            self.local_mac = local_mac
+        else:
+            self.local_mac = [0,0,0,0,0,0]
+        if nh_mac != None:
+            self.nh_mac = nh_mac
+        else:
+            self.nh_mac = [0,0,0,0,0,0]
+        if src_ip != None:
+            self.src_ip = src_ip
+        else:
+            self.src_ip = 0
+        if dst_ip != None:
+            self.dst_ip = dst_ip
+        else:
+            self.dst_ip = 0
+        if dscp != None:
+            self.dscp = dscp
+        else:
+            self.dscp = 0
+        if ttl != None:
+            self.ttl = ttl
+        else:
+            self.ttl = 0
+        if vpn != None:
+            self.vpn = vpn
+        else:
+            self.vpn = 0
+        if rate_limit != None:
+            self.rate_limit = rate_limit
+        else:
+            self.rate_limit = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.flags))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(util.pack_port_no(self.loopback_port_no))
+        packed.append(struct.pack("!6B", *self.local_mac))
+        packed.append(struct.pack("!6B", *self.nh_mac))
+        packed.append(struct.pack("!L", self.src_ip))
+        packed.append(struct.pack("!L", self.dst_ip))
+        packed.append(struct.pack("!B", self.dscp))
+        packed.append(struct.pack("!B", self.ttl))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.vpn))
+        packed.append(struct.pack("!L", self.rate_limit))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_l2gre()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.flags = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.loopback_port_no = util.unpack_port_no(reader)
+        obj.local_mac = list(reader.read('!6B'))
+        obj.nh_mac = list(reader.read('!6B'))
+        obj.src_ip = reader.read("!L")[0]
+        obj.dst_ip = reader.read("!L")[0]
+        obj.dscp = reader.read("!B")[0]
+        obj.ttl = reader.read("!B")[0]
+        reader.skip(2)
+        obj.vpn = reader.read("!L")[0]
+        obj.rate_limit = reader.read("!L")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.loopback_port_no != other.loopback_port_no: return False
+        if self.local_mac != other.local_mac: return False
+        if self.nh_mac != other.nh_mac: return False
+        if self.src_ip != other.src_ip: return False
+        if self.dst_ip != other.dst_ip: return False
+        if self.dscp != other.dscp: return False
+        if self.ttl != other.ttl: return False
+        if self.vpn != other.vpn: return False
+        if self.rate_limit != other.rate_limit: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_l2gre {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("loopback_port_no = ");
+                q.text(util.pretty_port(self.loopback_port_no))
+                q.text(","); q.breakable()
+                q.text("local_mac = ");
+                q.text(util.pretty_mac(self.local_mac))
+                q.text(","); q.breakable()
+                q.text("nh_mac = ");
+                q.text(util.pretty_mac(self.nh_mac))
+                q.text(","); q.breakable()
+                q.text("src_ip = ");
+                q.text(util.pretty_ipv4(self.src_ip))
+                q.text(","); q.breakable()
+                q.text("dst_ip = ");
+                q.text(util.pretty_ipv4(self.dst_ip))
+                q.text(","); q.breakable()
+                q.text("dscp = ");
+                q.text("%#x" % self.dscp)
+                q.text(","); q.breakable()
+                q.text("ttl = ");
+                q.text("%#x" % self.ttl)
+                q.text(","); q.breakable()
+                q.text("vpn = ");
+                q.text("%#x" % self.vpn)
+                q.text(","); q.breakable()
+                q.text("rate_limit = ");
+                q.text("%#x" % self.rate_limit)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[1] = bsn_vport_l2gre
+
+class bsn_vport_q_in_q(bsn_vport):
+    type = 0
+
+    def __init__(self, port_no=None, ingress_tpid=None, ingress_vlan_id=None, egress_tpid=None, egress_vlan_id=None, if_name=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if ingress_tpid != None:
+            self.ingress_tpid = ingress_tpid
+        else:
+            self.ingress_tpid = 0
+        if ingress_vlan_id != None:
+            self.ingress_vlan_id = ingress_vlan_id
+        else:
+            self.ingress_vlan_id = 0
+        if egress_tpid != None:
+            self.egress_tpid = egress_tpid
+        else:
+            self.egress_tpid = 0
+        if egress_vlan_id != None:
+            self.egress_vlan_id = egress_vlan_id
+        else:
+            self.egress_vlan_id = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.port_no))
+        packed.append(struct.pack("!H", self.ingress_tpid))
+        packed.append(struct.pack("!H", self.ingress_vlan_id))
+        packed.append(struct.pack("!H", self.egress_tpid))
+        packed.append(struct.pack("!H", self.egress_vlan_id))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_q_in_q()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.port_no = reader.read("!L")[0]
+        obj.ingress_tpid = reader.read("!H")[0]
+        obj.ingress_vlan_id = reader.read("!H")[0]
+        obj.egress_tpid = reader.read("!H")[0]
+        obj.egress_vlan_id = reader.read("!H")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.ingress_tpid != other.ingress_tpid: return False
+        if self.ingress_vlan_id != other.ingress_vlan_id: return False
+        if self.egress_tpid != other.egress_tpid: return False
+        if self.egress_vlan_id != other.egress_vlan_id: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_q_in_q {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text("%#x" % self.port_no)
+                q.text(","); q.breakable()
+                q.text("ingress_tpid = ");
+                q.text("%#x" % self.ingress_tpid)
+                q.text(","); q.breakable()
+                q.text("ingress_vlan_id = ");
+                q.text("%#x" % self.ingress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("egress_tpid = ");
+                q.text("%#x" % self.egress_tpid)
+                q.text(","); q.breakable()
+                q.text("egress_vlan_id = ");
+                q.text("%#x" % self.egress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[0] = bsn_vport_q_in_q
+
+class bsn_vrf_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, vrf=None, values=None):
+        if vrf != None:
+            self.vrf = vrf
+        else:
+            self.vrf = 0
+        if values != None:
+            self.values = values
+        else:
+            self.values = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.vrf))
+        packed.append(loxi.generic_util.pack_list(self.values))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_counter_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.vrf = reader.read("!L")[0]
+        obj.values = loxi.generic_util.unpack_list(reader, ofp.common.uint64.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vrf != other.vrf: return False
+        if self.values != other.values: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vrf = ");
+                q.text("%#x" % self.vrf)
+                q.text(","); q.breakable()
+                q.text("values = ");
+                q.pp(self.values)
+            q.breakable()
+        q.text('}')
+
+
+class bucket(loxi.OFObject):
+
+    def __init__(self, weight=None, watch_port=None, watch_group=None, actions=None):
+        if weight != None:
+            self.weight = weight
+        else:
+            self.weight = 0
+        if watch_port != None:
+            self.watch_port = watch_port
+        else:
+            self.watch_port = 0
+        if watch_group != None:
+            self.watch_group = watch_group
+        else:
+            self.watch_group = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 0
+        packed.append(struct.pack("!H", self.weight))
+        packed.append(util.pack_port_no(self.watch_port))
+        packed.append(struct.pack("!L", self.watch_group))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket()
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 2)
+        obj.weight = reader.read("!H")[0]
+        obj.watch_port = util.unpack_port_no(reader)
+        obj.watch_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.weight != other.weight: return False
+        if self.watch_port != other.watch_port: return False
+        if self.watch_group != other.watch_group: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("weight = ");
+                q.text("%#x" % self.weight)
+                q.text(","); q.breakable()
+                q.text("watch_port = ");
+                q.text(util.pretty_port(self.watch_port))
+                q.text(","); q.breakable()
+                q.text("watch_group = ");
+                q.text("%#x" % self.watch_group)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+
+class bucket_counter(loxi.OFObject):
+
+    def __init__(self, packet_count=None, byte_count=None):
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket_counter()
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket_counter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+            q.breakable()
+        q.text('}')
+
+
+class flow_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, duration_sec=None, duration_nsec=None, priority=None, idle_timeout=None, hard_timeout=None, flags=None, importance=None, cookie=None, packet_count=None, byte_count=None, match=None, instructions=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if importance != None:
+            self.importance = importance
+        else:
+            self.importance = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.importance))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.importance = reader.read("!H")[0]
+        reader.skip(2)
+        obj.cookie = reader.read("!Q")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.priority != other.priority: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.flags != other.flags: return False
+        if self.importance != other.importance: return False
+        if self.cookie != other.cookie: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("importance = ");
+                q.text("%#x" % self.importance)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+
+class group_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_type=None, group_id=None, buckets=None):
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+
+class group_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_id=None, ref_count=None, packet_count=None, byte_count=None, duration_sec=None, duration_nsec=None, bucket_stats=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if ref_count != None:
+            self.ref_count = ref_count
+        else:
+            self.ref_count = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if bucket_stats != None:
+            self.bucket_stats = bucket_stats
+        else:
+            self.bucket_stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(struct.pack("!L", self.ref_count))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(loxi.generic_util.pack_list(self.bucket_stats))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.group_id = reader.read("!L")[0]
+        obj.ref_count = reader.read("!L")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.bucket_stats = loxi.generic_util.unpack_list(reader, ofp.common.bucket_counter.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        if self.ref_count != other.ref_count: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.bucket_stats != other.bucket_stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("ref_count = ");
+                q.text("%#x" % self.ref_count)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("bucket_stats = ");
+                q.pp(self.bucket_stats)
+            q.breakable()
+        q.text('}')
+
+
+class hello_elem(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = hello_elem.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = hello_elem()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_elem {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class hello_elem_versionbitmap(hello_elem):
+    type = 1
+
+    def __init__(self, bitmaps=None):
+        if bitmaps != None:
+            self.bitmaps = bitmaps
+        else:
+            self.bitmaps = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.bitmaps))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello_elem_versionbitmap()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.bitmaps = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.bitmaps != other.bitmaps: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_elem_versionbitmap {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("bitmaps = ");
+                q.pp(self.bitmaps)
+            q.breakable()
+        q.text('}')
+
+hello_elem.subtypes[1] = hello_elem_versionbitmap
+
+class match_v3(loxi.OFObject):
+    type = 1
+
+    def __init__(self, oxm_list=None):
+        if oxm_list != None:
+            self.oxm_list = oxm_list
+        else:
+            self.oxm_list = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_list))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = match_v3()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_list = loxi.generic_util.unpack_list(reader, ofp.oxm.oxm.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_list != other.oxm_list: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("match_v3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_list = ");
+                q.pp(self.oxm_list)
+            q.breakable()
+        q.text('}')
+
+
+class meter_band_stats(loxi.OFObject):
+
+    def __init__(self, packet_band_count=None, byte_band_count=None):
+        if packet_band_count != None:
+            self.packet_band_count = packet_band_count
+        else:
+            self.packet_band_count = 0
+        if byte_band_count != None:
+            self.byte_band_count = byte_band_count
+        else:
+            self.byte_band_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.packet_band_count))
+        packed.append(struct.pack("!Q", self.byte_band_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_band_stats()
+        obj.packet_band_count = reader.read("!Q")[0]
+        obj.byte_band_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.packet_band_count != other.packet_band_count: return False
+        if self.byte_band_count != other.byte_band_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_band_stats {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("packet_band_count = ");
+                q.text("%#x" % self.packet_band_count)
+                q.text(","); q.breakable()
+                q.text("byte_band_count = ");
+                q.text("%#x" % self.byte_band_count)
+            q.breakable()
+        q.text('}')
+
+
+class meter_config(loxi.OFObject):
+
+    def __init__(self, flags=None, meter_id=None, entries=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_config()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.flags = reader.read("!H")[0]
+        obj.meter_id = reader.read("!L")[0]
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.meter_band.meter_band.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_config {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+
+class meter_features(loxi.OFObject):
+
+    def __init__(self, max_meter=None, band_types=None, capabilities=None, max_bands=None, max_color=None):
+        if max_meter != None:
+            self.max_meter = max_meter
+        else:
+            self.max_meter = 0
+        if band_types != None:
+            self.band_types = band_types
+        else:
+            self.band_types = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if max_bands != None:
+            self.max_bands = max_bands
+        else:
+            self.max_bands = 0
+        if max_color != None:
+            self.max_color = max_color
+        else:
+            self.max_color = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.max_meter))
+        packed.append(struct.pack("!L", self.band_types))
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!B", self.max_bands))
+        packed.append(struct.pack("!B", self.max_color))
+        packed.append('\x00' * 2)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_features()
+        obj.max_meter = reader.read("!L")[0]
+        obj.band_types = reader.read("!L")[0]
+        obj.capabilities = reader.read("!L")[0]
+        obj.max_bands = reader.read("!B")[0]
+        obj.max_color = reader.read("!B")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.max_meter != other.max_meter: return False
+        if self.band_types != other.band_types: return False
+        if self.capabilities != other.capabilities: return False
+        if self.max_bands != other.max_bands: return False
+        if self.max_color != other.max_color: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_features {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("max_meter = ");
+                q.text("%#x" % self.max_meter)
+                q.text(","); q.breakable()
+                q.text("band_types = ");
+                q.text("%#x" % self.band_types)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("max_bands = ");
+                q.text("%#x" % self.max_bands)
+                q.text(","); q.breakable()
+                q.text("max_color = ");
+                q.text("%#x" % self.max_color)
+            q.breakable()
+        q.text('}')
+
+
+class meter_stats(loxi.OFObject):
+
+    def __init__(self, meter_id=None, flow_count=None, packet_in_count=None, byte_in_count=None, duration_sec=None, duration_nsec=None, band_stats=None):
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        if flow_count != None:
+            self.flow_count = flow_count
+        else:
+            self.flow_count = 0
+        if packet_in_count != None:
+            self.packet_in_count = packet_in_count
+        else:
+            self.packet_in_count = 0
+        if byte_in_count != None:
+            self.byte_in_count = byte_in_count
+        else:
+            self.byte_in_count = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if band_stats != None:
+            self.band_stats = band_stats
+        else:
+            self.band_stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 6)
+        packed.append(struct.pack("!L", self.flow_count))
+        packed.append(struct.pack("!Q", self.packet_in_count))
+        packed.append(struct.pack("!Q", self.byte_in_count))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(loxi.generic_util.pack_list(self.band_stats))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_stats()
+        obj.meter_id = reader.read("!L")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 6)
+        reader.skip(6)
+        obj.flow_count = reader.read("!L")[0]
+        obj.packet_in_count = reader.read("!Q")[0]
+        obj.byte_in_count = reader.read("!Q")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.band_stats = loxi.generic_util.unpack_list(reader, ofp.common.meter_band_stats.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.meter_id != other.meter_id: return False
+        if self.flow_count != other.flow_count: return False
+        if self.packet_in_count != other.packet_in_count: return False
+        if self.byte_in_count != other.byte_in_count: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.band_stats != other.band_stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_stats {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+                q.text(","); q.breakable()
+                q.text("flow_count = ");
+                q.text("%#x" % self.flow_count)
+                q.text(","); q.breakable()
+                q.text("packet_in_count = ");
+                q.text("%#x" % self.packet_in_count)
+                q.text(","); q.breakable()
+                q.text("byte_in_count = ");
+                q.text("%#x" % self.byte_in_count)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("band_stats = ");
+                q.pp(self.band_stats)
+            q.breakable()
+        q.text('}')
+
+
+class packet_queue(loxi.OFObject):
+
+    def __init__(self, queue_id=None, port=None, properties=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 2
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_queue()
+        obj.queue_id = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 10)
+        reader.skip(6)
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.common.queue_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        if self.port != other.port: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class port_desc(loxi.OFObject):
+
+    def __init__(self, port_no=None, hw_addr=None, name=None, config=None, state=None, properties=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if state != None:
+            self.state = state
+        else:
+            self.state = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.state))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc()
+        obj.port_no = util.unpack_port_no(reader)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 6)
+        reader.skip(2)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.config = reader.read("!L")[0]
+        obj.state = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.port_desc_prop.port_desc_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.config != other.config: return False
+        if self.state != other.state: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("state = ");
+                q.text("%#x" % self.state)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class port_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, duration_sec=None, duration_nsec=None, rx_packets=None, tx_packets=None, rx_bytes=None, tx_bytes=None, rx_dropped=None, tx_dropped=None, rx_errors=None, tx_errors=None, properties=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if rx_packets != None:
+            self.rx_packets = rx_packets
+        else:
+            self.rx_packets = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if rx_bytes != None:
+            self.rx_bytes = rx_bytes
+        else:
+            self.rx_bytes = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if rx_dropped != None:
+            self.rx_dropped = rx_dropped
+        else:
+            self.rx_dropped = 0
+        if tx_dropped != None:
+            self.tx_dropped = tx_dropped
+        else:
+            self.tx_dropped = 0
+        if rx_errors != None:
+            self.rx_errors = rx_errors
+        else:
+            self.rx_errors = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!Q", self.rx_packets))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.rx_bytes))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.rx_dropped))
+        packed.append(struct.pack("!Q", self.tx_dropped))
+        packed.append(struct.pack("!Q", self.rx_errors))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.rx_packets = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.rx_bytes = reader.read("!Q")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.rx_dropped = reader.read("!Q")[0]
+        obj.tx_dropped = reader.read("!Q")[0]
+        obj.rx_errors = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.port_stats_prop.port_stats_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.rx_packets != other.rx_packets: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.rx_bytes != other.rx_bytes: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.rx_dropped != other.rx_dropped: return False
+        if self.tx_dropped != other.tx_dropped: return False
+        if self.rx_errors != other.rx_errors: return False
+        if self.tx_errors != other.tx_errors: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("rx_packets = ");
+                q.text("%#x" % self.rx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("rx_bytes = ");
+                q.text("%#x" % self.rx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("rx_dropped = ");
+                q.text("%#x" % self.rx_dropped)
+                q.text(","); q.breakable()
+                q.text("tx_dropped = ");
+                q.text("%#x" % self.tx_dropped)
+                q.text(","); q.breakable()
+                q.text("rx_errors = ");
+                q.text("%#x" % self.rx_errors)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class queue_desc(loxi.OFObject):
+
+    def __init__(self, port_no=None, queue_id=None, properties=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_desc()
+        obj.port_no = reader.read("!L")[0]
+        obj.queue_id = reader.read("!L")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 10)
+        reader.skip(6)
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.queue_desc_prop.queue_desc_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_desc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text("%#x" % self.port_no)
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = queue_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop_experimenter(queue_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append('\x00' * 4)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = queue_prop_experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop_experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        reader.skip(4)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[65535] = queue_prop_experimenter
+
+class queue_prop_max_rate(queue_prop):
+    type = 2
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_max_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_max_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[2] = queue_prop_max_rate
+
+class queue_prop_min_rate(queue_prop):
+    type = 1
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_min_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_min_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[1] = queue_prop_min_rate
+
+class queue_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, queue_id=None, tx_bytes=None, tx_packets=None, tx_errors=None, duration_sec=None, duration_nsec=None, properties=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 6)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(6)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.queue_stats_prop.queue_stats_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.tx_errors != other.tx_errors: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class table_desc(loxi.OFObject):
+
+    def __init__(self, table_id=None, config=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.config))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_desc()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.config = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.config != other.config: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_desc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+            q.breakable()
+        q.text('}')
+
+
+class table_feature_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = table_feature_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_feature_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class table_feature_prop_apply_actions(table_feature_prop):
+    type = 6
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[6] = table_feature_prop_apply_actions
+
+class table_feature_prop_apply_actions_miss(table_feature_prop):
+    type = 7
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_actions_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_actions_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[7] = table_feature_prop_apply_actions_miss
+
+class table_feature_prop_apply_setfield(table_feature_prop):
+    type = 14
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_setfield()
+        _type = reader.read("!H")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_setfield {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[14] = table_feature_prop_apply_setfield
+
+class table_feature_prop_apply_setfield_miss(table_feature_prop):
+    type = 15
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_setfield_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_setfield_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[15] = table_feature_prop_apply_setfield_miss
+
+class table_feature_prop_experimenter(table_feature_prop):
+    subtypes = {}
+
+    type = 65534
+
+    def __init__(self, experimenter=None, subtype=None, experimenter_data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if experimenter_data != None:
+            self.experimenter_data = experimenter_data
+        else:
+            self.experimenter_data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.experimenter_data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = table_feature_prop_experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_feature_prop_experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65534)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.experimenter_data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.experimenter_data != other.experimenter_data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("experimenter_data = ");
+                q.pp(self.experimenter_data)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[65534] = table_feature_prop_experimenter
+
+class table_feature_prop_experimenter_miss(table_feature_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, subtype=None, experimenter_data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if experimenter_data != None:
+            self.experimenter_data = experimenter_data
+        else:
+            self.experimenter_data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.experimenter_data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = table_feature_prop_experimenter_miss.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_feature_prop_experimenter_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.experimenter_data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.experimenter_data != other.experimenter_data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_experimenter_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("experimenter_data = ");
+                q.pp(self.experimenter_data)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[65535] = table_feature_prop_experimenter_miss
+
+class table_feature_prop_instructions(table_feature_prop):
+    type = 0
+
+    def __init__(self, instruction_ids=None):
+        if instruction_ids != None:
+            self.instruction_ids = instruction_ids
+        else:
+            self.instruction_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.instruction_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_instructions()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.instruction_ids = loxi.generic_util.unpack_list(reader, ofp.instruction_id.instruction_id.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.instruction_ids != other.instruction_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_instructions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("instruction_ids = ");
+                q.pp(self.instruction_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[0] = table_feature_prop_instructions
+
+class table_feature_prop_instructions_miss(table_feature_prop):
+    type = 1
+
+    def __init__(self, instruction_ids=None):
+        if instruction_ids != None:
+            self.instruction_ids = instruction_ids
+        else:
+            self.instruction_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.instruction_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_instructions_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.instruction_ids = loxi.generic_util.unpack_list(reader, ofp.instruction_id.instruction_id.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.instruction_ids != other.instruction_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_instructions_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("instruction_ids = ");
+                q.pp(self.instruction_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[1] = table_feature_prop_instructions_miss
+
+class table_feature_prop_match(table_feature_prop):
+    type = 8
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_match()
+        _type = reader.read("!H")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_match {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[8] = table_feature_prop_match
+
+class table_feature_prop_next_tables(table_feature_prop):
+    type = 2
+
+    def __init__(self, next_table_ids=None):
+        if next_table_ids != None:
+            self.next_table_ids = next_table_ids
+        else:
+            self.next_table_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.next_table_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_next_tables()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.next_table_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint8.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.next_table_ids != other.next_table_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_next_tables {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("next_table_ids = ");
+                q.pp(self.next_table_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[2] = table_feature_prop_next_tables
+
+class table_feature_prop_next_tables_miss(table_feature_prop):
+    type = 3
+
+    def __init__(self, next_table_ids=None):
+        if next_table_ids != None:
+            self.next_table_ids = next_table_ids
+        else:
+            self.next_table_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.next_table_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_next_tables_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.next_table_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint8.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.next_table_ids != other.next_table_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_next_tables_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("next_table_ids = ");
+                q.pp(self.next_table_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[3] = table_feature_prop_next_tables_miss
+
+class table_feature_prop_table_sync_from(table_feature_prop):
+    type = 16
+
+    def __init__(self, table_ids=None):
+        if table_ids != None:
+            self.table_ids = table_ids
+        else:
+            self.table_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.table_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_table_sync_from()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.table_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint8.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_ids != other.table_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_table_sync_from {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_ids = ");
+                q.pp(self.table_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[16] = table_feature_prop_table_sync_from
+
+class table_feature_prop_wildcards(table_feature_prop):
+    type = 10
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_wildcards()
+        _type = reader.read("!H")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_wildcards {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[10] = table_feature_prop_wildcards
+
+class table_feature_prop_write_actions(table_feature_prop):
+    type = 4
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[4] = table_feature_prop_write_actions
+
+class table_feature_prop_write_actions_miss(table_feature_prop):
+    type = 5
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_actions_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_actions_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[5] = table_feature_prop_write_actions_miss
+
+class table_feature_prop_write_setfield(table_feature_prop):
+    type = 12
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_setfield()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_setfield {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[12] = table_feature_prop_write_setfield
+
+class table_feature_prop_write_setfield_miss(table_feature_prop):
+    type = 13
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_setfield_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_setfield_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[13] = table_feature_prop_write_setfield_miss
+
+class table_features(loxi.OFObject):
+
+    def __init__(self, table_id=None, name=None, metadata_match=None, metadata_write=None, config=None, max_entries=None, properties=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if metadata_match != None:
+            self.metadata_match = metadata_match
+        else:
+            self.metadata_match = 0
+        if metadata_write != None:
+            self.metadata_write = metadata_write
+        else:
+            self.metadata_write = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if max_entries != None:
+            self.max_entries = max_entries
+        else:
+            self.max_entries = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 5)
+        packed.append(struct.pack("!32s", self.name))
+        packed.append(struct.pack("!Q", self.metadata_match))
+        packed.append(struct.pack("!Q", self.metadata_write))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.max_entries))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(5)
+        obj.name = reader.read("!32s")[0].rstrip("\x00")
+        obj.metadata_match = reader.read("!Q")[0]
+        obj.metadata_write = reader.read("!Q")[0]
+        obj.config = reader.read("!L")[0]
+        obj.max_entries = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.common.table_feature_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.name != other.name: return False
+        if self.metadata_match != other.metadata_match: return False
+        if self.metadata_write != other.metadata_write: return False
+        if self.config != other.config: return False
+        if self.max_entries != other.max_entries: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("metadata_match = ");
+                q.text("%#x" % self.metadata_match)
+                q.text(","); q.breakable()
+                q.text("metadata_write = ");
+                q.text("%#x" % self.metadata_write)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("max_entries = ");
+                q.text("%#x" % self.max_entries)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class table_mod_prop_eviction(loxi.OFObject):
+    type = 2
+
+    def __init__(self, flags=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.flags))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod_prop_eviction()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.flags = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_prop_eviction {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+
+class table_mod_prop_experimenter(loxi.OFObject):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, exp_type=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = table_mod_prop_experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_mod_prop_experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.exp_type = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_prop_experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("exp_type = ");
+                q.text("%#x" % self.exp_type)
+            q.breakable()
+        q.text('}')
+
+
+class table_mod_prop_vacancy(loxi.OFObject):
+    type = 3
+
+    def __init__(self, vacancy_down=None, vacancy_up=None, vacancy=None):
+        if vacancy_down != None:
+            self.vacancy_down = vacancy_down
+        else:
+            self.vacancy_down = 0
+        if vacancy_up != None:
+            self.vacancy_up = vacancy_up
+        else:
+            self.vacancy_up = 0
+        if vacancy != None:
+            self.vacancy = vacancy
+        else:
+            self.vacancy = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.vacancy_down))
+        packed.append(struct.pack("!B", self.vacancy_up))
+        packed.append(struct.pack("!B", self.vacancy))
+        packed.append('\x00' * 1)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod_prop_vacancy()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.vacancy_down = reader.read("!B")[0]
+        obj.vacancy_up = reader.read("!B")[0]
+        obj.vacancy = reader.read("!B")[0]
+        reader.skip(1)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vacancy_down != other.vacancy_down: return False
+        if self.vacancy_up != other.vacancy_up: return False
+        if self.vacancy != other.vacancy: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_prop_vacancy {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vacancy_down = ");
+                q.text("%#x" % self.vacancy_down)
+                q.text(","); q.breakable()
+                q.text("vacancy_up = ");
+                q.text("%#x" % self.vacancy_up)
+                q.text(","); q.breakable()
+                q.text("vacancy = ");
+                q.text("%#x" % self.vacancy)
+            q.breakable()
+        q.text('}')
+
+
+class table_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, active_count=None, lookup_count=None, matched_count=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if active_count != None:
+            self.active_count = active_count
+        else:
+            self.active_count = 0
+        if lookup_count != None:
+            self.lookup_count = lookup_count
+        else:
+            self.lookup_count = 0
+        if matched_count != None:
+            self.matched_count = matched_count
+        else:
+            self.matched_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.active_count))
+        packed.append(struct.pack("!Q", self.lookup_count))
+        packed.append(struct.pack("!Q", self.matched_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_entry()
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.active_count = reader.read("!L")[0]
+        obj.lookup_count = reader.read("!Q")[0]
+        obj.matched_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.active_count != other.active_count: return False
+        if self.lookup_count != other.lookup_count: return False
+        if self.matched_count != other.matched_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("active_count = ");
+                q.text("%#x" % self.active_count)
+                q.text(","); q.breakable()
+                q.text("lookup_count = ");
+                q.text("%#x" % self.lookup_count)
+                q.text(","); q.breakable()
+                q.text("matched_count = ");
+                q.text("%#x" % self.matched_count)
+            q.breakable()
+        q.text('}')
+
+
+class uint32(loxi.OFObject):
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = uint32()
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("uint32 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+class uint64(loxi.OFObject):
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = uint64()
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("uint64 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+class uint8(loxi.OFObject):
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = uint8()
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("uint8 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+
+match = match_v3
diff --git a/Fabric/Utilities/src/python/loxi/of14/const.py b/Fabric/Utilities/src/python/loxi/of14/const.py
new file mode 100644
index 0000000..93fd169
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/const.py
@@ -0,0 +1,1514 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template const.py
+# Do not modify
+
+OFP_VERSION = 5
+
+# Identifiers from group macro_definitions
+OFP_MAX_TABLE_NAME_LEN = 32
+OFP_MAX_PORT_NAME_LEN = 16
+OFP_TCP_PORT = 6653
+OFP_SSL_PORT = 6653
+OFP_ETH_ALEN = 6
+OFP_DEFAULT_MISS_SEND_LEN = 128
+OFP_VLAN_NONE = 0
+OFP_FLOW_PERMANENT = 0
+OFP_DEFAULT_PRIORITY = 32768
+OFP_NO_BUFFER = 4294967295
+DESC_STR_LEN = 256
+SERIAL_NUM_LEN = 32
+OFPQ_ALL = 4294967295
+OFPQ_MAX_RATE_UNCFG = 65535
+OFPQ_MIN_RATE_UNCFG = 65535
+
+# Identifiers from group of_bsn_lacp_convergence_status
+LACP_SUCCESS = 0
+LACP_TIMEDOUT = 1
+LACP_OUT_OF_SYNC = 2
+
+of_bsn_lacp_convergence_status_map = {
+    0: 'LACP_SUCCESS',
+    1: 'LACP_TIMEDOUT',
+    2: 'LACP_OUT_OF_SYNC',
+}
+
+# Identifiers from group of_bsn_pdu_slot_num
+BSN_PDU_SLOT_NUM_ANY = 255
+
+of_bsn_pdu_slot_num_map = {
+    255: 'BSN_PDU_SLOT_NUM_ANY',
+}
+
+# Identifiers from group of_bsn_vlan_counter
+OFP_BSN_VLAN_COUNTER_RX_BYTES = 0
+OFP_BSN_VLAN_COUNTER_RX_PACKETS = 1
+OFP_BSN_VLAN_COUNTER_TX_BYTES = 2
+OFP_BSN_VLAN_COUNTER_TX_PACKETS = 3
+
+of_bsn_vlan_counter_map = {
+    0: 'OFP_BSN_VLAN_COUNTER_RX_BYTES',
+    1: 'OFP_BSN_VLAN_COUNTER_RX_PACKETS',
+    2: 'OFP_BSN_VLAN_COUNTER_TX_BYTES',
+    3: 'OFP_BSN_VLAN_COUNTER_TX_PACKETS',
+}
+
+# Identifiers from group of_bsn_vrf_counter
+OFP_BSN_VRF_COUNTER_BYTES = 0
+OFP_BSN_VRF_COUNTER_PACKETS = 1
+
+of_bsn_vrf_counter_map = {
+    0: 'OFP_BSN_VRF_COUNTER_BYTES',
+    1: 'OFP_BSN_VRF_COUNTER_PACKETS',
+}
+
+# Identifiers from group ofp_action_type
+OFPAT_OUTPUT = 0
+OFPAT_COPY_TTL_OUT = 11
+OFPAT_COPY_TTL_IN = 12
+OFPAT_SET_MPLS_TTL = 15
+OFPAT_DEC_MPLS_TTL = 16
+OFPAT_PUSH_VLAN = 17
+OFPAT_POP_VLAN = 18
+OFPAT_PUSH_MPLS = 19
+OFPAT_POP_MPLS = 20
+OFPAT_SET_QUEUE = 21
+OFPAT_GROUP = 22
+OFPAT_SET_NW_TTL = 23
+OFPAT_DEC_NW_TTL = 24
+OFPAT_SET_FIELD = 25
+OFPAT_PUSH_PBB = 26
+OFPAT_POP_PBB = 27
+OFPAT_EXPERIMENTER = 65535
+
+ofp_action_type_map = {
+    0: 'OFPAT_OUTPUT',
+    11: 'OFPAT_COPY_TTL_OUT',
+    12: 'OFPAT_COPY_TTL_IN',
+    15: 'OFPAT_SET_MPLS_TTL',
+    16: 'OFPAT_DEC_MPLS_TTL',
+    17: 'OFPAT_PUSH_VLAN',
+    18: 'OFPAT_POP_VLAN',
+    19: 'OFPAT_PUSH_MPLS',
+    20: 'OFPAT_POP_MPLS',
+    21: 'OFPAT_SET_QUEUE',
+    22: 'OFPAT_GROUP',
+    23: 'OFPAT_SET_NW_TTL',
+    24: 'OFPAT_DEC_NW_TTL',
+    25: 'OFPAT_SET_FIELD',
+    26: 'OFPAT_PUSH_PBB',
+    27: 'OFPAT_POP_PBB',
+    65535: 'OFPAT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_async_config_failed_code
+OFPACFC_INVALID = 0
+OFPACFC_UNSUPPORTED = 1
+OFPACFC_EPERM = 2
+
+ofp_async_config_failed_code_map = {
+    0: 'OFPACFC_INVALID',
+    1: 'OFPACFC_UNSUPPORTED',
+    2: 'OFPACFC_EPERM',
+}
+
+# Identifiers from group ofp_bad_action_code
+OFPBAC_BAD_TYPE = 0
+OFPBAC_BAD_LEN = 1
+OFPBAC_BAD_EXPERIMENTER = 2
+OFPBAC_BAD_EXPERIMENTER_TYPE = 3
+OFPBAC_BAD_OUT_PORT = 4
+OFPBAC_BAD_ARGUMENT = 5
+OFPBAC_EPERM = 6
+OFPBAC_TOO_MANY = 7
+OFPBAC_BAD_QUEUE = 8
+OFPBAC_BAD_OUT_GROUP = 9
+OFPBAC_MATCH_INCONSISTENT = 10
+OFPBAC_UNSUPPORTED_ORDER = 11
+OFPBAC_BAD_TAG = 12
+OFPBAC_BAD_SET_TYPE = 13
+OFPBAC_BAD_SET_LEN = 14
+OFPBAC_BAD_SET_ARGUMENT = 15
+
+ofp_bad_action_code_map = {
+    0: 'OFPBAC_BAD_TYPE',
+    1: 'OFPBAC_BAD_LEN',
+    2: 'OFPBAC_BAD_EXPERIMENTER',
+    3: 'OFPBAC_BAD_EXPERIMENTER_TYPE',
+    4: 'OFPBAC_BAD_OUT_PORT',
+    5: 'OFPBAC_BAD_ARGUMENT',
+    6: 'OFPBAC_EPERM',
+    7: 'OFPBAC_TOO_MANY',
+    8: 'OFPBAC_BAD_QUEUE',
+    9: 'OFPBAC_BAD_OUT_GROUP',
+    10: 'OFPBAC_MATCH_INCONSISTENT',
+    11: 'OFPBAC_UNSUPPORTED_ORDER',
+    12: 'OFPBAC_BAD_TAG',
+    13: 'OFPBAC_BAD_SET_TYPE',
+    14: 'OFPBAC_BAD_SET_LEN',
+    15: 'OFPBAC_BAD_SET_ARGUMENT',
+}
+
+# Identifiers from group ofp_bad_instruction_code
+OFPBIC_UNKNOWN_INST = 0
+OFPBIC_UNSUP_INST = 1
+OFPBIC_BAD_TABLE_ID = 2
+OFPBIC_UNSUP_METADATA = 3
+OFPBIC_UNSUP_METADATA_MASK = 4
+OFPBIC_BAD_EXPERIMENTER = 5
+OFPBIC_BAD_EXPERIMENTER_TYPE = 6
+OFPBIC_BAD_LEN = 7
+OFPBIC_EPERM = 8
+OFPBIC_DUP_INST = 9
+
+ofp_bad_instruction_code_map = {
+    0: 'OFPBIC_UNKNOWN_INST',
+    1: 'OFPBIC_UNSUP_INST',
+    2: 'OFPBIC_BAD_TABLE_ID',
+    3: 'OFPBIC_UNSUP_METADATA',
+    4: 'OFPBIC_UNSUP_METADATA_MASK',
+    5: 'OFPBIC_BAD_EXPERIMENTER',
+    6: 'OFPBIC_BAD_EXPERIMENTER_TYPE',
+    7: 'OFPBIC_BAD_LEN',
+    8: 'OFPBIC_EPERM',
+    9: 'OFPBIC_DUP_INST',
+}
+
+# Identifiers from group ofp_bad_match_code
+OFPBMC_BAD_TYPE = 0
+OFPBMC_BAD_LEN = 1
+OFPBMC_BAD_TAG = 2
+OFPBMC_BAD_DL_ADDR_MASK = 3
+OFPBMC_BAD_NW_ADDR_MASK = 4
+OFPBMC_BAD_WILDCARDS = 5
+OFPBMC_BAD_FIELD = 6
+OFPBMC_BAD_VALUE = 7
+OFPBMC_BAD_MASK = 8
+OFPBMC_BAD_PREREQ = 9
+OFPBMC_DUP_FIELD = 10
+OFPBMC_EPERM = 11
+
+ofp_bad_match_code_map = {
+    0: 'OFPBMC_BAD_TYPE',
+    1: 'OFPBMC_BAD_LEN',
+    2: 'OFPBMC_BAD_TAG',
+    3: 'OFPBMC_BAD_DL_ADDR_MASK',
+    4: 'OFPBMC_BAD_NW_ADDR_MASK',
+    5: 'OFPBMC_BAD_WILDCARDS',
+    6: 'OFPBMC_BAD_FIELD',
+    7: 'OFPBMC_BAD_VALUE',
+    8: 'OFPBMC_BAD_MASK',
+    9: 'OFPBMC_BAD_PREREQ',
+    10: 'OFPBMC_DUP_FIELD',
+    11: 'OFPBMC_EPERM',
+}
+
+# Identifiers from group ofp_bad_property_code
+OFPBPC_BAD_TYPE = 0
+OFPBPC_BAD_LEN = 1
+OFPBPC_BAD_VALUE = 2
+OFPBPC_TOO_MANY = 3
+OFPBPC_DUP_TYPE = 4
+OFPBPC_BAD_EXPERIMENTER = 5
+OFPBPC_BAD_EXP_TYPE = 6
+OFPBPC_BAD_EXP_VALUE = 7
+OFPBPC_EPERM = 8
+
+ofp_bad_property_code_map = {
+    0: 'OFPBPC_BAD_TYPE',
+    1: 'OFPBPC_BAD_LEN',
+    2: 'OFPBPC_BAD_VALUE',
+    3: 'OFPBPC_TOO_MANY',
+    4: 'OFPBPC_DUP_TYPE',
+    5: 'OFPBPC_BAD_EXPERIMENTER',
+    6: 'OFPBPC_BAD_EXP_TYPE',
+    7: 'OFPBPC_BAD_EXP_VALUE',
+    8: 'OFPBPC_EPERM',
+}
+
+# Identifiers from group ofp_bad_request_code
+OFPBRC_BAD_VERSION = 0
+OFPBRC_BAD_TYPE = 1
+OFPBRC_BAD_STAT = 2
+OFPBRC_BAD_EXPERIMENTER = 3
+OFPBRC_BAD_EXPERIMENTER_TYPE = 4
+OFPBRC_EPERM = 5
+OFPBRC_BAD_LEN = 6
+OFPBRC_BUFFER_EMPTY = 7
+OFPBRC_BUFFER_UNKNOWN = 8
+OFPBRC_BAD_TABLE_ID = 9
+OFPBRC_IS_SLAVE = 10
+OFPBRC_BAD_PORT = 11
+OFPBRC_BAD_PACKET = 12
+OFPBRC_MULTIPART_BUFFER_OVERFLOW = 13
+OFPBRC_MULTIPART_REQUEST_TIMEOUT = 14
+OFPBRC_MULTIPART_REPLY_TIMEOUT = 15
+
+ofp_bad_request_code_map = {
+    0: 'OFPBRC_BAD_VERSION',
+    1: 'OFPBRC_BAD_TYPE',
+    2: 'OFPBRC_BAD_STAT',
+    3: 'OFPBRC_BAD_EXPERIMENTER',
+    4: 'OFPBRC_BAD_EXPERIMENTER_TYPE',
+    5: 'OFPBRC_EPERM',
+    6: 'OFPBRC_BAD_LEN',
+    7: 'OFPBRC_BUFFER_EMPTY',
+    8: 'OFPBRC_BUFFER_UNKNOWN',
+    9: 'OFPBRC_BAD_TABLE_ID',
+    10: 'OFPBRC_IS_SLAVE',
+    11: 'OFPBRC_BAD_PORT',
+    12: 'OFPBRC_BAD_PACKET',
+    13: 'OFPBRC_MULTIPART_BUFFER_OVERFLOW',
+    14: 'OFPBRC_MULTIPART_REQUEST_TIMEOUT',
+    15: 'OFPBRC_MULTIPART_REPLY_TIMEOUT',
+}
+
+# Identifiers from group ofp_bsn_anchor
+OFP_BSN_ANCHOR_PACKET_START = 0
+OFP_BSN_ANCHOR_L3_HEADER_START = 1
+OFP_BSN_ANCHOR_L4_HEADER_START = 2
+OFP_BSN_ANCHOR_L4_PAYLOAD_START = 3
+
+ofp_bsn_anchor_map = {
+    0: 'OFP_BSN_ANCHOR_PACKET_START',
+    1: 'OFP_BSN_ANCHOR_L3_HEADER_START',
+    2: 'OFP_BSN_ANCHOR_L4_HEADER_START',
+    3: 'OFP_BSN_ANCHOR_L4_PAYLOAD_START',
+}
+
+# Identifiers from group ofp_bsn_controller_connection_state
+OFP_BSN_CONTROLLER_CONNECTION_STATE_DISCONNECTED = 0
+OFP_BSN_CONTROLLER_CONNECTION_STATE_CONNECTED = 1
+
+ofp_bsn_controller_connection_state_map = {
+    0: 'OFP_BSN_CONTROLLER_CONNECTION_STATE_DISCONNECTED',
+    1: 'OFP_BSN_CONTROLLER_CONNECTION_STATE_CONNECTED',
+}
+
+# Identifiers from group ofp_bsn_lacp_state
+OFP_BSN_LACP_STATE_ACTIVITY = 1
+OFP_BSN_LACP_STATE_TIMEOUT = 2
+OFP_BSN_LACP_STATE_AGGREGATION = 4
+OFP_BSN_LACP_STATE_SYNCHRONIZATION = 8
+OFP_BSN_LACP_STATE_COLLECTING = 16
+OFP_BSN_LACP_STATE_DISTRIBUTING = 32
+OFP_BSN_LACP_STATE_DEFAULTED = 64
+OFP_BSN_LACP_STATE_EXPIRED = 128
+
+ofp_bsn_lacp_state_map = {
+    1: 'OFP_BSN_LACP_STATE_ACTIVITY',
+    2: 'OFP_BSN_LACP_STATE_TIMEOUT',
+    4: 'OFP_BSN_LACP_STATE_AGGREGATION',
+    8: 'OFP_BSN_LACP_STATE_SYNCHRONIZATION',
+    16: 'OFP_BSN_LACP_STATE_COLLECTING',
+    32: 'OFP_BSN_LACP_STATE_DISTRIBUTING',
+    64: 'OFP_BSN_LACP_STATE_DEFAULTED',
+    128: 'OFP_BSN_LACP_STATE_EXPIRED',
+}
+
+# Identifiers from group ofp_bsn_loglevel
+OFP_BSN_LOGLEVEL_MSG = 0
+OFP_BSN_LOGLEVEL_ERROR = 1
+OFP_BSN_LOGLEVEL_WARN = 2
+OFP_BSN_LOGLEVEL_INFO = 3
+OFP_BSN_LOGLEVEL_VERBOSE = 4
+OFP_BSN_LOGLEVEL_TRACE = 5
+
+ofp_bsn_loglevel_map = {
+    0: 'OFP_BSN_LOGLEVEL_MSG',
+    1: 'OFP_BSN_LOGLEVEL_ERROR',
+    2: 'OFP_BSN_LOGLEVEL_WARN',
+    3: 'OFP_BSN_LOGLEVEL_INFO',
+    4: 'OFP_BSN_LOGLEVEL_VERBOSE',
+    5: 'OFP_BSN_LOGLEVEL_TRACE',
+}
+
+# Identifiers from group ofp_bsn_lua_upload_flags
+OFP_BSN_LUA_UPLOAD_MORE = 1
+OFP_BSN_LUA_UPLOAD_FORCE = 2
+
+ofp_bsn_lua_upload_flags_map = {
+    1: 'OFP_BSN_LUA_UPLOAD_MORE',
+    2: 'OFP_BSN_LUA_UPLOAD_FORCE',
+}
+
+# Identifiers from group ofp_bsn_pktin_flag
+OFP_BSN_PKTIN_FLAG_PDU = 1
+OFP_BSN_PKTIN_FLAG_NEW_HOST = 2
+OFP_BSN_PKTIN_FLAG_STATION_MOVE = 4
+OFP_BSN_PKTIN_FLAG_ARP = 8
+OFP_BSN_PKTIN_FLAG_DHCP = 16
+OFP_BSN_PKTIN_FLAG_L2_CPU = 32
+OFP_BSN_PKTIN_FLAG_DEBUG = 64
+OFP_BSN_PKTIN_FLAG_TTL_EXPIRED = 128
+OFP_BSN_PKTIN_FLAG_L3_MISS = 256
+OFP_BSN_PKTIN_FLAG_L3_CPU = 512
+OFP_BSN_PKTIN_FLAG_INGRESS_ACL = 1024
+OFP_BSN_PKTIN_FLAG_SFLOW = 2048
+OFP_BSN_PKTIN_FLAG_ARP_CACHE = 4096
+OFP_BSN_PKTIN_FLAG_ARP_TARGET = 8192
+
+ofp_bsn_pktin_flag_map = {
+    1: 'OFP_BSN_PKTIN_FLAG_PDU',
+    2: 'OFP_BSN_PKTIN_FLAG_NEW_HOST',
+    4: 'OFP_BSN_PKTIN_FLAG_STATION_MOVE',
+    8: 'OFP_BSN_PKTIN_FLAG_ARP',
+    16: 'OFP_BSN_PKTIN_FLAG_DHCP',
+    32: 'OFP_BSN_PKTIN_FLAG_L2_CPU',
+    64: 'OFP_BSN_PKTIN_FLAG_DEBUG',
+    128: 'OFP_BSN_PKTIN_FLAG_TTL_EXPIRED',
+    256: 'OFP_BSN_PKTIN_FLAG_L3_MISS',
+    512: 'OFP_BSN_PKTIN_FLAG_L3_CPU',
+    1024: 'OFP_BSN_PKTIN_FLAG_INGRESS_ACL',
+    2048: 'OFP_BSN_PKTIN_FLAG_SFLOW',
+    4096: 'OFP_BSN_PKTIN_FLAG_ARP_CACHE',
+    8192: 'OFP_BSN_PKTIN_FLAG_ARP_TARGET',
+}
+
+# Identifiers from group ofp_bsn_port_counter
+OFP_BSN_PORT_COUNTER_RX_BYTES = 0
+OFP_BSN_PORT_COUNTER_RX_PACKETS_UNICAST = 1
+OFP_BSN_PORT_COUNTER_RX_PACKETS_BROADCAST = 2
+OFP_BSN_PORT_COUNTER_RX_PACKETS_MULTICAST = 3
+OFP_BSN_PORT_COUNTER_RX_DROPPED = 4
+OFP_BSN_PORT_COUNTER_RX_ERRORS = 5
+OFP_BSN_PORT_COUNTER_TX_BYTES = 6
+OFP_BSN_PORT_COUNTER_TX_PACKETS_UNICAST = 7
+OFP_BSN_PORT_COUNTER_TX_PACKETS_BROADCAST = 8
+OFP_BSN_PORT_COUNTER_TX_PACKETS_MULTICAST = 9
+OFP_BSN_PORT_COUNTER_TX_DROPPED = 10
+OFP_BSN_PORT_COUNTER_TX_ERRORS = 11
+OFP_BSN_PORT_COUNTER_RX_RUNTS = 12
+OFP_BSN_PORT_COUNTER_RX_GIANTS = 13
+OFP_BSN_PORT_COUNTER_RX_CRC_ERRORS = 14
+OFP_BSN_PORT_COUNTER_RX_ALIGNMENT_ERRORS = 15
+OFP_BSN_PORT_COUNTER_RX_SYMBOL_ERRORS = 16
+OFP_BSN_PORT_COUNTER_RX_PAUSE_INPUT = 17
+OFP_BSN_PORT_COUNTER_TX_COLLISIONS = 18
+OFP_BSN_PORT_COUNTER_TX_LATE_COLLISIONS = 19
+OFP_BSN_PORT_COUNTER_TX_DEFERRED = 20
+OFP_BSN_PORT_COUNTER_TX_PAUSE_OUTPUT = 21
+OFP_BSN_PORT_COUNTER_RX_PACKETS = 22
+OFP_BSN_PORT_COUNTER_TX_PACKETS = 23
+OFP_BSN_PORT_COUNTER_RX_LENGTH_ERRORS = 24
+OFP_BSN_PORT_COUNTER_RX_OVERFLOW_ERRORS = 25
+OFP_BSN_PORT_COUNTER_TX_CARRIER_ERRORS = 26
+OFP_BSN_PORT_COUNTER_RX_PACKETS_BAD_VLAN = 27
+
+ofp_bsn_port_counter_map = {
+    0: 'OFP_BSN_PORT_COUNTER_RX_BYTES',
+    1: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_UNICAST',
+    2: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_BROADCAST',
+    3: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_MULTICAST',
+    4: 'OFP_BSN_PORT_COUNTER_RX_DROPPED',
+    5: 'OFP_BSN_PORT_COUNTER_RX_ERRORS',
+    6: 'OFP_BSN_PORT_COUNTER_TX_BYTES',
+    7: 'OFP_BSN_PORT_COUNTER_TX_PACKETS_UNICAST',
+    8: 'OFP_BSN_PORT_COUNTER_TX_PACKETS_BROADCAST',
+    9: 'OFP_BSN_PORT_COUNTER_TX_PACKETS_MULTICAST',
+    10: 'OFP_BSN_PORT_COUNTER_TX_DROPPED',
+    11: 'OFP_BSN_PORT_COUNTER_TX_ERRORS',
+    12: 'OFP_BSN_PORT_COUNTER_RX_RUNTS',
+    13: 'OFP_BSN_PORT_COUNTER_RX_GIANTS',
+    14: 'OFP_BSN_PORT_COUNTER_RX_CRC_ERRORS',
+    15: 'OFP_BSN_PORT_COUNTER_RX_ALIGNMENT_ERRORS',
+    16: 'OFP_BSN_PORT_COUNTER_RX_SYMBOL_ERRORS',
+    17: 'OFP_BSN_PORT_COUNTER_RX_PAUSE_INPUT',
+    18: 'OFP_BSN_PORT_COUNTER_TX_COLLISIONS',
+    19: 'OFP_BSN_PORT_COUNTER_TX_LATE_COLLISIONS',
+    20: 'OFP_BSN_PORT_COUNTER_TX_DEFERRED',
+    21: 'OFP_BSN_PORT_COUNTER_TX_PAUSE_OUTPUT',
+    22: 'OFP_BSN_PORT_COUNTER_RX_PACKETS',
+    23: 'OFP_BSN_PORT_COUNTER_TX_PACKETS',
+    24: 'OFP_BSN_PORT_COUNTER_RX_LENGTH_ERRORS',
+    25: 'OFP_BSN_PORT_COUNTER_RX_OVERFLOW_ERRORS',
+    26: 'OFP_BSN_PORT_COUNTER_TX_CARRIER_ERRORS',
+    27: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_BAD_VLAN',
+}
+
+# Identifiers from group ofp_bsn_tcp_flag
+OFP_BSN_TCP_FLAG_FIN = 1
+OFP_BSN_TCP_FLAG_SYN = 2
+OFP_BSN_TCP_FLAG_RST = 4
+OFP_BSN_TCP_FLAG_PSH = 8
+OFP_BSN_TCP_FLAG_ACK = 16
+OFP_BSN_TCP_FLAG_URG = 32
+OFP_BSN_TCP_FLAG_ECE = 64
+OFP_BSN_TCP_FLAG_CWR = 128
+OFP_BSN_TCP_FLAG_NS = 256
+
+ofp_bsn_tcp_flag_map = {
+    1: 'OFP_BSN_TCP_FLAG_FIN',
+    2: 'OFP_BSN_TCP_FLAG_SYN',
+    4: 'OFP_BSN_TCP_FLAG_RST',
+    8: 'OFP_BSN_TCP_FLAG_PSH',
+    16: 'OFP_BSN_TCP_FLAG_ACK',
+    32: 'OFP_BSN_TCP_FLAG_URG',
+    64: 'OFP_BSN_TCP_FLAG_ECE',
+    128: 'OFP_BSN_TCP_FLAG_CWR',
+    256: 'OFP_BSN_TCP_FLAG_NS',
+}
+
+# Identifiers from group ofp_bsn_udf_anchor
+OFP_BSN_UDF_ANCHOR_PACKET_START = 0
+OFP_BSN_UDF_ANCHOR_L3_HEADER_START = 1
+OFP_BSN_UDF_ANCHOR_L4_HEADER_START = 2
+
+ofp_bsn_udf_anchor_map = {
+    0: 'OFP_BSN_UDF_ANCHOR_PACKET_START',
+    1: 'OFP_BSN_UDF_ANCHOR_L3_HEADER_START',
+    2: 'OFP_BSN_UDF_ANCHOR_L4_HEADER_START',
+}
+
+# Identifiers from group ofp_bsn_vlan_counter_constants
+OFP_BSN_VLAN_ALL = 65535
+
+ofp_bsn_vlan_counter_constants_map = {
+    65535: 'OFP_BSN_VLAN_ALL',
+}
+
+# Identifiers from group ofp_bsn_vport_l2gre_flags
+OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID = 1
+OF_BSN_VPORT_L2GRE_DSCP_ASSIGN = 2
+OF_BSN_VPORT_L2GRE_DSCP_COPY = 4
+OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID = 8
+OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID = 16
+
+ofp_bsn_vport_l2gre_flags_map = {
+    1: 'OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID',
+    2: 'OF_BSN_VPORT_L2GRE_DSCP_ASSIGN',
+    4: 'OF_BSN_VPORT_L2GRE_DSCP_COPY',
+    8: 'OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID',
+    16: 'OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID',
+}
+
+# Identifiers from group ofp_bsn_vport_q_in_q_untagged
+OF_BSN_VPORT_Q_IN_Q_UNTAGGED = 65535
+
+ofp_bsn_vport_q_in_q_untagged_map = {
+    65535: 'OF_BSN_VPORT_Q_IN_Q_UNTAGGED',
+}
+
+# Identifiers from group ofp_bsn_vport_status
+OF_BSN_VPORT_STATUS_OK = 0
+OF_BSN_VPORT_STATUS_FAILED = 1
+
+ofp_bsn_vport_status_map = {
+    0: 'OF_BSN_VPORT_STATUS_OK',
+    1: 'OF_BSN_VPORT_STATUS_FAILED',
+}
+
+# Identifiers from group ofp_bsn_vrf_counter_constants
+OFP_BSN_VRF_ALL = 4294967295
+
+ofp_bsn_vrf_counter_constants_map = {
+    4294967295: 'OFP_BSN_VRF_ALL',
+}
+
+# Identifiers from group ofp_bundle_ctrl_type
+OFPBCT_OPEN_REQUEST = 0
+OFPBCT_OPEN_REPLY = 1
+OFPBCT_CLOSE_REQUEST = 2
+OFPBCT_CLOSE_REPLY = 3
+OFPBCT_COMMIT_REQUEST = 4
+OFPBCT_COMMIT_REPLY = 5
+OFPBCT_DISCARD_REQUEST = 6
+OFPBCT_DISCARD_REPLY = 7
+
+ofp_bundle_ctrl_type_map = {
+    0: 'OFPBCT_OPEN_REQUEST',
+    1: 'OFPBCT_OPEN_REPLY',
+    2: 'OFPBCT_CLOSE_REQUEST',
+    3: 'OFPBCT_CLOSE_REPLY',
+    4: 'OFPBCT_COMMIT_REQUEST',
+    5: 'OFPBCT_COMMIT_REPLY',
+    6: 'OFPBCT_DISCARD_REQUEST',
+    7: 'OFPBCT_DISCARD_REPLY',
+}
+
+# Identifiers from group ofp_bundle_failed_code
+OFPBFC_UNKNOWN = 0
+OFPBFC_EPERM = 1
+OFPBFC_BAD_ID = 2
+OFPBFC_BUNDLE_EXIST = 3
+OFPBFC_BUNDLE_CLOSED = 4
+OFPBFC_OUT_OF_BUNDLES = 5
+OFPBFC_BAD_TYPE = 6
+OFPBFC_BAD_FLAGS = 7
+OFPBFC_MSG_BAD_LEN = 8
+OFPBFC_MSG_BAD_XID = 9
+OFPBFC_MSG_UNSUP = 10
+OFPBFC_MSG_CONFLICT = 11
+OFPBFC_MSG_TOO_MANY = 12
+OFPBFC_MSG_FAILED = 13
+OFPBFC_TIMEOUT = 14
+OFPBFC_BUNDLE_IN_PROGRESS = 15
+
+ofp_bundle_failed_code_map = {
+    0: 'OFPBFC_UNKNOWN',
+    1: 'OFPBFC_EPERM',
+    2: 'OFPBFC_BAD_ID',
+    3: 'OFPBFC_BUNDLE_EXIST',
+    4: 'OFPBFC_BUNDLE_CLOSED',
+    5: 'OFPBFC_OUT_OF_BUNDLES',
+    6: 'OFPBFC_BAD_TYPE',
+    7: 'OFPBFC_BAD_FLAGS',
+    8: 'OFPBFC_MSG_BAD_LEN',
+    9: 'OFPBFC_MSG_BAD_XID',
+    10: 'OFPBFC_MSG_UNSUP',
+    11: 'OFPBFC_MSG_CONFLICT',
+    12: 'OFPBFC_MSG_TOO_MANY',
+    13: 'OFPBFC_MSG_FAILED',
+    14: 'OFPBFC_TIMEOUT',
+    15: 'OFPBFC_BUNDLE_IN_PROGRESS',
+}
+
+# Identifiers from group ofp_bundle_flags
+OFPBF_ATOMIC = 1
+OFPBF_ORDERED = 2
+
+ofp_bundle_flags_map = {
+    1: 'OFPBF_ATOMIC',
+    2: 'OFPBF_ORDERED',
+}
+
+# Identifiers from group ofp_capabilities
+OFPC_FLOW_STATS = 1
+OFPC_TABLE_STATS = 2
+OFPC_PORT_STATS = 4
+OFPC_GROUP_STATS = 8
+OFPC_IP_REASM = 32
+OFPC_QUEUE_STATS = 64
+OFPC_PORT_BLOCKED = 256
+
+ofp_capabilities_map = {
+    1: 'OFPC_FLOW_STATS',
+    2: 'OFPC_TABLE_STATS',
+    4: 'OFPC_PORT_STATS',
+    8: 'OFPC_GROUP_STATS',
+    32: 'OFPC_IP_REASM',
+    64: 'OFPC_QUEUE_STATS',
+    256: 'OFPC_PORT_BLOCKED',
+}
+
+# Identifiers from group ofp_config_flags
+OFPC_FRAG_NORMAL = 0
+OFPC_FRAG_DROP = 1
+OFPC_FRAG_REASM = 2
+OFPC_FRAG_MASK = 3
+
+ofp_config_flags_map = {
+    0: 'OFPC_FRAG_NORMAL',
+    1: 'OFPC_FRAG_DROP',
+    2: 'OFPC_FRAG_REASM',
+    3: 'OFPC_FRAG_MASK',
+}
+
+# Identifiers from group ofp_controller_max_len
+OFPCML_MAX = 65509
+OFPCML_NO_BUFFER = 65535
+
+ofp_controller_max_len_map = {
+    65509: 'OFPCML_MAX',
+    65535: 'OFPCML_NO_BUFFER',
+}
+
+# Identifiers from group ofp_controller_role
+OFPCR_ROLE_NOCHANGE = 0
+OFPCR_ROLE_EQUAL = 1
+OFPCR_ROLE_MASTER = 2
+OFPCR_ROLE_SLAVE = 3
+
+ofp_controller_role_map = {
+    0: 'OFPCR_ROLE_NOCHANGE',
+    1: 'OFPCR_ROLE_EQUAL',
+    2: 'OFPCR_ROLE_MASTER',
+    3: 'OFPCR_ROLE_SLAVE',
+}
+
+# Identifiers from group ofp_controller_role_reason
+OFPCRR_MASTER_REQUEST = 0
+OFPCRR_CONFIG = 1
+OFPCRR_EXPERIMENTER = 2
+
+ofp_controller_role_reason_map = {
+    0: 'OFPCRR_MASTER_REQUEST',
+    1: 'OFPCRR_CONFIG',
+    2: 'OFPCRR_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_error_type
+OFPET_HELLO_FAILED = 0
+OFPET_BAD_REQUEST = 1
+OFPET_BAD_ACTION = 2
+OFPET_BAD_INSTRUCTION = 3
+OFPET_BAD_MATCH = 4
+OFPET_FLOW_MOD_FAILED = 5
+OFPET_GROUP_MOD_FAILED = 6
+OFPET_PORT_MOD_FAILED = 7
+OFPET_TABLE_MOD_FAILED = 8
+OFPET_QUEUE_OP_FAILED = 9
+OFPET_SWITCH_CONFIG_FAILED = 10
+OFPET_ROLE_REQUEST_FAILED = 11
+OFPET_METER_MOD_FAILED = 12
+OFPET_TABLE_FEATURES_FAILED = 13
+OFPET_BAD_PROPERTY = 14
+OFPET_ASYNC_CONFIG_FAILED = 15
+OFPET_FLOW_MONITOR_FAILED = 16
+OFPET_BUNDLE_FAILED = 17
+OFPET_EXPERIMENTER = 65535
+
+ofp_error_type_map = {
+    0: 'OFPET_HELLO_FAILED',
+    1: 'OFPET_BAD_REQUEST',
+    2: 'OFPET_BAD_ACTION',
+    3: 'OFPET_BAD_INSTRUCTION',
+    4: 'OFPET_BAD_MATCH',
+    5: 'OFPET_FLOW_MOD_FAILED',
+    6: 'OFPET_GROUP_MOD_FAILED',
+    7: 'OFPET_PORT_MOD_FAILED',
+    8: 'OFPET_TABLE_MOD_FAILED',
+    9: 'OFPET_QUEUE_OP_FAILED',
+    10: 'OFPET_SWITCH_CONFIG_FAILED',
+    11: 'OFPET_ROLE_REQUEST_FAILED',
+    12: 'OFPET_METER_MOD_FAILED',
+    13: 'OFPET_TABLE_FEATURES_FAILED',
+    14: 'OFPET_BAD_PROPERTY',
+    15: 'OFPET_ASYNC_CONFIG_FAILED',
+    16: 'OFPET_FLOW_MONITOR_FAILED',
+    17: 'OFPET_BUNDLE_FAILED',
+    65535: 'OFPET_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_flow_mod_command
+OFPFC_ADD = 0
+OFPFC_MODIFY = 1
+OFPFC_MODIFY_STRICT = 2
+OFPFC_DELETE = 3
+OFPFC_DELETE_STRICT = 4
+
+ofp_flow_mod_command_map = {
+    0: 'OFPFC_ADD',
+    1: 'OFPFC_MODIFY',
+    2: 'OFPFC_MODIFY_STRICT',
+    3: 'OFPFC_DELETE',
+    4: 'OFPFC_DELETE_STRICT',
+}
+
+# Identifiers from group ofp_flow_mod_failed_code
+OFPFMFC_UNKNOWN = 0
+OFPFMFC_TABLE_FULL = 1
+OFPFMFC_BAD_TABLE_ID = 2
+OFPFMFC_OVERLAP = 3
+OFPFMFC_EPERM = 4
+OFPFMFC_BAD_TIMEOUT = 5
+OFPFMFC_BAD_COMMAND = 6
+OFPFMFC_BAD_FLAGS = 7
+OFPFMFC_CANT_SYNC = 8
+OFPFMFC_BAD_PRIORITY = 9
+
+ofp_flow_mod_failed_code_map = {
+    0: 'OFPFMFC_UNKNOWN',
+    1: 'OFPFMFC_TABLE_FULL',
+    2: 'OFPFMFC_BAD_TABLE_ID',
+    3: 'OFPFMFC_OVERLAP',
+    4: 'OFPFMFC_EPERM',
+    5: 'OFPFMFC_BAD_TIMEOUT',
+    6: 'OFPFMFC_BAD_COMMAND',
+    7: 'OFPFMFC_BAD_FLAGS',
+    8: 'OFPFMFC_CANT_SYNC',
+    9: 'OFPFMFC_BAD_PRIORITY',
+}
+
+# Identifiers from group ofp_flow_mod_flags
+OFPFF_SEND_FLOW_REM = 1
+OFPFF_CHECK_OVERLAP = 2
+OFPFF_RESET_COUNTS = 4
+OFPFF_NO_PKT_COUNTS = 8
+OFPFF_NO_BYT_COUNTS = 16
+OFPFF_BSN_SEND_IDLE = 128
+
+ofp_flow_mod_flags_map = {
+    1: 'OFPFF_SEND_FLOW_REM',
+    2: 'OFPFF_CHECK_OVERLAP',
+    4: 'OFPFF_RESET_COUNTS',
+    8: 'OFPFF_NO_PKT_COUNTS',
+    16: 'OFPFF_NO_BYT_COUNTS',
+    128: 'OFPFF_BSN_SEND_IDLE',
+}
+
+# Identifiers from group ofp_flow_monitor_failed_code
+OFPMOFC_UNKNOWN = 0
+OFPMOFC_MONITOR_EXISTS = 1
+OFPMOFC_INVALID_MONITOR = 2
+OFPMOFC_UNKNOWN_MONITOR = 3
+OFPMOFC_BAD_COMMAND = 4
+OFPMOFC_BAD_FLAGS = 5
+OFPMOFC_BAD_TABLE_ID = 6
+OFPMOFC_BAD_OUT = 7
+
+ofp_flow_monitor_failed_code_map = {
+    0: 'OFPMOFC_UNKNOWN',
+    1: 'OFPMOFC_MONITOR_EXISTS',
+    2: 'OFPMOFC_INVALID_MONITOR',
+    3: 'OFPMOFC_UNKNOWN_MONITOR',
+    4: 'OFPMOFC_BAD_COMMAND',
+    5: 'OFPMOFC_BAD_FLAGS',
+    6: 'OFPMOFC_BAD_TABLE_ID',
+    7: 'OFPMOFC_BAD_OUT',
+}
+
+# Identifiers from group ofp_flow_removed_reason
+OFPRR_IDLE_TIMEOUT = 0
+OFPRR_HARD_TIMEOUT = 1
+OFPRR_DELETE = 2
+OFPRR_GROUP_DELETE = 3
+OFPRR_METER_DELETE = 4
+OFPRR_EVICTION = 5
+
+ofp_flow_removed_reason_map = {
+    0: 'OFPRR_IDLE_TIMEOUT',
+    1: 'OFPRR_HARD_TIMEOUT',
+    2: 'OFPRR_DELETE',
+    3: 'OFPRR_GROUP_DELETE',
+    4: 'OFPRR_METER_DELETE',
+    5: 'OFPRR_EVICTION',
+}
+
+# Identifiers from group ofp_group
+OFPG_MAX = 4294967040
+OFPG_ALL = 4294967292
+OFPG_ANY = 4294967295
+
+ofp_group_map = {
+    4294967040: 'OFPG_MAX',
+    4294967292: 'OFPG_ALL',
+    4294967295: 'OFPG_ANY',
+}
+
+# Identifiers from group ofp_group_capabilities
+OFPGFC_SELECT_WEIGHT = 1
+OFPGFC_SELECT_LIVENESS = 2
+OFPGFC_CHAINING = 4
+OFPGFC_CHAINING_CHECKS = 8
+
+ofp_group_capabilities_map = {
+    1: 'OFPGFC_SELECT_WEIGHT',
+    2: 'OFPGFC_SELECT_LIVENESS',
+    4: 'OFPGFC_CHAINING',
+    8: 'OFPGFC_CHAINING_CHECKS',
+}
+
+# Identifiers from group ofp_group_mod_command
+OFPGC_ADD = 0
+OFPGC_MODIFY = 1
+OFPGC_DELETE = 2
+
+ofp_group_mod_command_map = {
+    0: 'OFPGC_ADD',
+    1: 'OFPGC_MODIFY',
+    2: 'OFPGC_DELETE',
+}
+
+# Identifiers from group ofp_group_mod_failed_code
+OFPGMFC_GROUP_EXISTS = 0
+OFPGMFC_INVALID_GROUP = 1
+OFPGMFC_WEIGHT_UNSUPPORTED = 2
+OFPGMFC_OUT_OF_GROUPS = 3
+OFPGMFC_OUT_OF_BUCKETS = 4
+OFPGMFC_CHAINING_UNSUPPORTED = 5
+OFPGMFC_WATCH_UNSUPPORTED = 6
+OFPGMFC_LOOP = 7
+OFPGMFC_UNKNOWN_GROUP = 8
+OFPGMFC_CHAINED_GROUP = 9
+OFPGMFC_BAD_TYPE = 10
+OFPGMFC_BAD_COMMAND = 11
+OFPGMFC_BAD_BUCKET = 12
+OFPGMFC_BAD_WATCH = 13
+OFPGMFC_EPERM = 14
+
+ofp_group_mod_failed_code_map = {
+    0: 'OFPGMFC_GROUP_EXISTS',
+    1: 'OFPGMFC_INVALID_GROUP',
+    2: 'OFPGMFC_WEIGHT_UNSUPPORTED',
+    3: 'OFPGMFC_OUT_OF_GROUPS',
+    4: 'OFPGMFC_OUT_OF_BUCKETS',
+    5: 'OFPGMFC_CHAINING_UNSUPPORTED',
+    6: 'OFPGMFC_WATCH_UNSUPPORTED',
+    7: 'OFPGMFC_LOOP',
+    8: 'OFPGMFC_UNKNOWN_GROUP',
+    9: 'OFPGMFC_CHAINED_GROUP',
+    10: 'OFPGMFC_BAD_TYPE',
+    11: 'OFPGMFC_BAD_COMMAND',
+    12: 'OFPGMFC_BAD_BUCKET',
+    13: 'OFPGMFC_BAD_WATCH',
+    14: 'OFPGMFC_EPERM',
+}
+
+# Identifiers from group ofp_group_type
+OFPGT_ALL = 0
+OFPGT_SELECT = 1
+OFPGT_INDIRECT = 2
+OFPGT_FF = 3
+
+ofp_group_type_map = {
+    0: 'OFPGT_ALL',
+    1: 'OFPGT_SELECT',
+    2: 'OFPGT_INDIRECT',
+    3: 'OFPGT_FF',
+}
+
+# Identifiers from group ofp_hello_elem_type
+OFPHET_VERSIONBITMAP = 1
+
+ofp_hello_elem_type_map = {
+    1: 'OFPHET_VERSIONBITMAP',
+}
+
+# Identifiers from group ofp_hello_failed_code
+OFPHFC_INCOMPATIBLE = 0
+OFPHFC_EPERM = 1
+
+ofp_hello_failed_code_map = {
+    0: 'OFPHFC_INCOMPATIBLE',
+    1: 'OFPHFC_EPERM',
+}
+
+# Identifiers from group ofp_instruction_type
+OFPIT_GOTO_TABLE = 1
+OFPIT_WRITE_METADATA = 2
+OFPIT_WRITE_ACTIONS = 3
+OFPIT_APPLY_ACTIONS = 4
+OFPIT_CLEAR_ACTIONS = 5
+OFPIT_METER = 6
+OFPIT_EXPERIMENTER = 65535
+
+ofp_instruction_type_map = {
+    1: 'OFPIT_GOTO_TABLE',
+    2: 'OFPIT_WRITE_METADATA',
+    3: 'OFPIT_WRITE_ACTIONS',
+    4: 'OFPIT_APPLY_ACTIONS',
+    5: 'OFPIT_CLEAR_ACTIONS',
+    6: 'OFPIT_METER',
+    65535: 'OFPIT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_ipv6exthdr_flags
+OFPIEH_NONEXT = 1
+OFPIEH_ESP = 2
+OFPIEH_AUTH = 4
+OFPIEH_DEST = 8
+OFPIEH_FRAG = 16
+OFPIEH_ROUTER = 32
+OFPIEH_HOP = 64
+OFPIEH_UNREP = 128
+OFPIEH_UNSEQ = 256
+
+ofp_ipv6exthdr_flags_map = {
+    1: 'OFPIEH_NONEXT',
+    2: 'OFPIEH_ESP',
+    4: 'OFPIEH_AUTH',
+    8: 'OFPIEH_DEST',
+    16: 'OFPIEH_FRAG',
+    32: 'OFPIEH_ROUTER',
+    64: 'OFPIEH_HOP',
+    128: 'OFPIEH_UNREP',
+    256: 'OFPIEH_UNSEQ',
+}
+
+# Identifiers from group ofp_match_type
+OFPMT_STANDARD = 0
+OFPMT_OXM = 1
+
+ofp_match_type_map = {
+    0: 'OFPMT_STANDARD',
+    1: 'OFPMT_OXM',
+}
+
+# Identifiers from group ofp_meter
+OFPM_MAX = 4294901760
+OFPM_SLOWPATH = 4294967293
+OFPM_CONTROLLER = 4294967294
+OFPM_ALL = 4294967295
+
+ofp_meter_map = {
+    4294901760: 'OFPM_MAX',
+    4294967293: 'OFPM_SLOWPATH',
+    4294967294: 'OFPM_CONTROLLER',
+    4294967295: 'OFPM_ALL',
+}
+
+# Identifiers from group ofp_meter_band_type
+OFPMBT_DROP = 1
+OFPMBT_DSCP_REMARK = 2
+OFPMBT_EXPERIMENTER = 65535
+
+ofp_meter_band_type_map = {
+    1: 'OFPMBT_DROP',
+    2: 'OFPMBT_DSCP_REMARK',
+    65535: 'OFPMBT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_meter_flags
+OFPMF_KBPS = 1
+OFPMF_PKTPS = 2
+OFPMF_BURST = 4
+OFPMF_STATS = 8
+
+ofp_meter_flags_map = {
+    1: 'OFPMF_KBPS',
+    2: 'OFPMF_PKTPS',
+    4: 'OFPMF_BURST',
+    8: 'OFPMF_STATS',
+}
+
+# Identifiers from group ofp_meter_mod_command
+OFPMC_ADD = 0
+OFPMC_MODIFY = 1
+OFPMC_DELETE = 2
+
+ofp_meter_mod_command_map = {
+    0: 'OFPMC_ADD',
+    1: 'OFPMC_MODIFY',
+    2: 'OFPMC_DELETE',
+}
+
+# Identifiers from group ofp_meter_mod_failed_code
+OFPMMFC_UNKNOWN = 0
+OFPMMFC_METER_EXISTS = 1
+OFPMMFC_INVALID_METER = 2
+OFPMMFC_UNKNOWN_METER = 3
+OFPMMFC_BAD_COMMAND = 4
+OFPMMFC_BAD_FLAGS = 5
+OFPMMFC_BAD_RATE = 6
+OFPMMFC_BAD_BURST = 7
+OFPMMFC_BAD_BAND = 8
+OFPMMFC_BAD_BAND_VALUE = 9
+OFPMMFC_OUT_OF_METERS = 10
+OFPMMFC_OUT_OF_BANDS = 11
+
+ofp_meter_mod_failed_code_map = {
+    0: 'OFPMMFC_UNKNOWN',
+    1: 'OFPMMFC_METER_EXISTS',
+    2: 'OFPMMFC_INVALID_METER',
+    3: 'OFPMMFC_UNKNOWN_METER',
+    4: 'OFPMMFC_BAD_COMMAND',
+    5: 'OFPMMFC_BAD_FLAGS',
+    6: 'OFPMMFC_BAD_RATE',
+    7: 'OFPMMFC_BAD_BURST',
+    8: 'OFPMMFC_BAD_BAND',
+    9: 'OFPMMFC_BAD_BAND_VALUE',
+    10: 'OFPMMFC_OUT_OF_METERS',
+    11: 'OFPMMFC_OUT_OF_BANDS',
+}
+
+# Identifiers from group ofp_optical_port_features
+OFPOPF_RX_TUNE = 1
+OFPOPF_TX_TUNE = 2
+OFPOPF_TX_PWR = 4
+OFPOPF_USE_FREQ = 8
+
+ofp_optical_port_features_map = {
+    1: 'OFPOPF_RX_TUNE',
+    2: 'OFPOPF_TX_TUNE',
+    4: 'OFPOPF_TX_PWR',
+    8: 'OFPOPF_USE_FREQ',
+}
+
+# Identifiers from group ofp_oxm_class
+OFPXMC_NXM_0 = 0
+OFPXMC_NXM_1 = 1
+OFPXMC_OPENFLOW_BASIC = 32768
+OFPXMC_EXPERIMENTER = 65535
+
+ofp_oxm_class_map = {
+    0: 'OFPXMC_NXM_0',
+    1: 'OFPXMC_NXM_1',
+    32768: 'OFPXMC_OPENFLOW_BASIC',
+    65535: 'OFPXMC_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_packet_in_reason
+OFPR_NO_MATCH = 0
+OFPR_ACTION = 1
+OFPR_INVALID_TTL = 2
+OFPR_ACTION_SET = 3
+OFPR_GROUP = 4
+OFPR_PACKET_OUT = 5
+OFPR_BSN_NEW_HOST = 128
+OFPR_BSN_STATION_MOVE = 129
+OFPR_BSN_BAD_VLAN = 130
+OFPR_BSN_DESTINATION_LOOKUP_FAILURE = 131
+OFPR_BSN_NO_ROUTE = 132
+OFPR_BSN_ICMP_ECHO_REQUEST = 133
+OFPR_BSN_DEST_NETWORK_UNREACHABLE = 134
+OFPR_BSN_DEST_HOST_UNREACHABLE = 135
+OFPR_BSN_DEST_PORT_UNREACHABLE = 136
+OFPR_BSN_FRAGMENTATION_REQUIRED = 137
+OFPR_BSN_ARP = 139
+OFPR_BSN_DHCP = 140
+OFPR_BSN_DEBUG = 141
+OFPR_BSN_PACKET_OF_DEATH = 142
+
+ofp_packet_in_reason_map = {
+    0: 'OFPR_NO_MATCH',
+    1: 'OFPR_ACTION',
+    2: 'OFPR_INVALID_TTL',
+    3: 'OFPR_ACTION_SET',
+    4: 'OFPR_GROUP',
+    5: 'OFPR_PACKET_OUT',
+    128: 'OFPR_BSN_NEW_HOST',
+    129: 'OFPR_BSN_STATION_MOVE',
+    130: 'OFPR_BSN_BAD_VLAN',
+    131: 'OFPR_BSN_DESTINATION_LOOKUP_FAILURE',
+    132: 'OFPR_BSN_NO_ROUTE',
+    133: 'OFPR_BSN_ICMP_ECHO_REQUEST',
+    134: 'OFPR_BSN_DEST_NETWORK_UNREACHABLE',
+    135: 'OFPR_BSN_DEST_HOST_UNREACHABLE',
+    136: 'OFPR_BSN_DEST_PORT_UNREACHABLE',
+    137: 'OFPR_BSN_FRAGMENTATION_REQUIRED',
+    139: 'OFPR_BSN_ARP',
+    140: 'OFPR_BSN_DHCP',
+    141: 'OFPR_BSN_DEBUG',
+    142: 'OFPR_BSN_PACKET_OF_DEATH',
+}
+
+# Identifiers from group ofp_port
+OFPP_MAX = 4294967040
+OFPP_IN_PORT = 4294967288
+OFPP_TABLE = 4294967289
+OFPP_NORMAL = 4294967290
+OFPP_FLOOD = 4294967291
+OFPP_ALL = 4294967292
+OFPP_CONTROLLER = 4294967293
+OFPP_LOCAL = 4294967294
+OFPP_ANY = 4294967295
+
+ofp_port_map = {
+    4294967040: 'OFPP_MAX',
+    4294967288: 'OFPP_IN_PORT',
+    4294967289: 'OFPP_TABLE',
+    4294967290: 'OFPP_NORMAL',
+    4294967291: 'OFPP_FLOOD',
+    4294967292: 'OFPP_ALL',
+    4294967293: 'OFPP_CONTROLLER',
+    4294967294: 'OFPP_LOCAL',
+    4294967295: 'OFPP_ANY',
+}
+
+# Identifiers from group ofp_port_config
+OFPPC_PORT_DOWN = 1
+OFPPC_NO_RECV = 4
+OFPPC_NO_FWD = 32
+OFPPC_NO_PACKET_IN = 64
+OFPPC_BSN_MIRROR_DEST = 2147483648
+
+ofp_port_config_map = {
+    1: 'OFPPC_PORT_DOWN',
+    4: 'OFPPC_NO_RECV',
+    32: 'OFPPC_NO_FWD',
+    64: 'OFPPC_NO_PACKET_IN',
+    2147483648: 'OFPPC_BSN_MIRROR_DEST',
+}
+
+# Identifiers from group ofp_port_features
+OFPPF_10MB_HD = 1
+OFPPF_10MB_FD = 2
+OFPPF_100MB_HD = 4
+OFPPF_100MB_FD = 8
+OFPPF_1GB_HD = 16
+OFPPF_1GB_FD = 32
+OFPPF_10GB_FD = 64
+OFPPF_40GB_FD = 128
+OFPPF_100GB_FD = 256
+OFPPF_1TB_FD = 512
+OFPPF_OTHER = 1024
+OFPPF_COPPER = 2048
+OFPPF_FIBER = 4096
+OFPPF_AUTONEG = 8192
+OFPPF_PAUSE = 16384
+OFPPF_PAUSE_ASYM = 32768
+OFPPF_BSN_BREAKOUT_CAPABLE = 2147483648
+
+ofp_port_features_map = {
+    1: 'OFPPF_10MB_HD',
+    2: 'OFPPF_10MB_FD',
+    4: 'OFPPF_100MB_HD',
+    8: 'OFPPF_100MB_FD',
+    16: 'OFPPF_1GB_HD',
+    32: 'OFPPF_1GB_FD',
+    64: 'OFPPF_10GB_FD',
+    128: 'OFPPF_40GB_FD',
+    256: 'OFPPF_100GB_FD',
+    512: 'OFPPF_1TB_FD',
+    1024: 'OFPPF_OTHER',
+    2048: 'OFPPF_COPPER',
+    4096: 'OFPPF_FIBER',
+    8192: 'OFPPF_AUTONEG',
+    16384: 'OFPPF_PAUSE',
+    32768: 'OFPPF_PAUSE_ASYM',
+    2147483648: 'OFPPF_BSN_BREAKOUT_CAPABLE',
+}
+
+# Identifiers from group ofp_port_mod_failed_code
+OFPPMFC_BAD_PORT = 0
+OFPPMFC_BAD_HW_ADDR = 1
+OFPPMFC_BAD_CONFIG = 2
+OFPPMFC_BAD_ADVERTISE = 3
+OFPPMFC_EPERM = 4
+
+ofp_port_mod_failed_code_map = {
+    0: 'OFPPMFC_BAD_PORT',
+    1: 'OFPPMFC_BAD_HW_ADDR',
+    2: 'OFPPMFC_BAD_CONFIG',
+    3: 'OFPPMFC_BAD_ADVERTISE',
+    4: 'OFPPMFC_EPERM',
+}
+
+# Identifiers from group ofp_port_reason
+OFPPR_ADD = 0
+OFPPR_DELETE = 1
+OFPPR_MODIFY = 2
+
+ofp_port_reason_map = {
+    0: 'OFPPR_ADD',
+    1: 'OFPPR_DELETE',
+    2: 'OFPPR_MODIFY',
+}
+
+# Identifiers from group ofp_port_state
+OFPPS_LINK_DOWN = 1
+OFPPS_BLOCKED = 2
+OFPPS_LIVE = 4
+
+ofp_port_state_map = {
+    1: 'OFPPS_LINK_DOWN',
+    2: 'OFPPS_BLOCKED',
+    4: 'OFPPS_LIVE',
+}
+
+# Identifiers from group ofp_port_stats_optical_flags
+OFPOSF_RX_TUNE = 1
+OFPOSF_TX_TUNE = 2
+OFPOSF_TX_PWR = 4
+OFPOSF_RX_PWR = 16
+OFPOSF_TX_BIAS = 32
+OFPOSF_TX_TEMP = 64
+
+ofp_port_stats_optical_flags_map = {
+    1: 'OFPOSF_RX_TUNE',
+    2: 'OFPOSF_TX_TUNE',
+    4: 'OFPOSF_TX_PWR',
+    16: 'OFPOSF_RX_PWR',
+    32: 'OFPOSF_TX_BIAS',
+    64: 'OFPOSF_TX_TEMP',
+}
+
+# Identifiers from group ofp_port_stats_prop_type
+OFPPSPT_ETHERNET = 0
+OFPPSPT_OPTICAL = 1
+OFPPSPT_EXPERIMENTER = 65535
+
+ofp_port_stats_prop_type_map = {
+    0: 'OFPPSPT_ETHERNET',
+    1: 'OFPPSPT_OPTICAL',
+    65535: 'OFPPSPT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_queue_op_failed_code
+OFPQOFC_BAD_PORT = 0
+OFPQOFC_BAD_QUEUE = 1
+OFPQOFC_EPERM = 2
+
+ofp_queue_op_failed_code_map = {
+    0: 'OFPQOFC_BAD_PORT',
+    1: 'OFPQOFC_BAD_QUEUE',
+    2: 'OFPQOFC_EPERM',
+}
+
+# Identifiers from group ofp_requestforward_reason
+OFPRFR_GROUP_MOD = 0
+OFPRFR_METER_MOD = 1
+
+ofp_requestforward_reason_map = {
+    0: 'OFPRFR_GROUP_MOD',
+    1: 'OFPRFR_METER_MOD',
+}
+
+# Identifiers from group ofp_role_request_failed_code
+OFPRRFC_STALE = 0
+OFPRRFC_UNSUP = 1
+OFPRRFC_BAD_ROLE = 2
+
+ofp_role_request_failed_code_map = {
+    0: 'OFPRRFC_STALE',
+    1: 'OFPRRFC_UNSUP',
+    2: 'OFPRRFC_BAD_ROLE',
+}
+
+# Identifiers from group ofp_stats_reply_flags
+OFPSF_REPLY_MORE = 1
+
+ofp_stats_reply_flags_map = {
+    1: 'OFPSF_REPLY_MORE',
+}
+
+# Identifiers from group ofp_stats_request_flags
+OFPSF_REQ_MORE = 1
+
+ofp_stats_request_flags_map = {
+    1: 'OFPSF_REQ_MORE',
+}
+
+# Identifiers from group ofp_stats_type
+OFPST_DESC = 0
+OFPST_FLOW = 1
+OFPST_AGGREGATE = 2
+OFPST_TABLE = 3
+OFPST_PORT = 4
+OFPST_QUEUE = 5
+OFPST_GROUP = 6
+OFPST_GROUP_DESC = 7
+OFPST_GROUP_FEATURES = 8
+OFPST_METER = 9
+OFPST_METER_CONFIG = 10
+OFPST_METER_FEATURES = 11
+OFPST_TABLE_FEATURES = 12
+OFPST_PORT_DESC = 13
+OFPMP_TABLE_DESC = 14
+OFPMP_QUEUE_DESC = 15
+OFPMP_FLOW_MONITOR = 16
+OFPST_EXPERIMENTER = 65535
+
+ofp_stats_type_map = {
+    0: 'OFPST_DESC',
+    1: 'OFPST_FLOW',
+    2: 'OFPST_AGGREGATE',
+    3: 'OFPST_TABLE',
+    4: 'OFPST_PORT',
+    5: 'OFPST_QUEUE',
+    6: 'OFPST_GROUP',
+    7: 'OFPST_GROUP_DESC',
+    8: 'OFPST_GROUP_FEATURES',
+    9: 'OFPST_METER',
+    10: 'OFPST_METER_CONFIG',
+    11: 'OFPST_METER_FEATURES',
+    12: 'OFPST_TABLE_FEATURES',
+    13: 'OFPST_PORT_DESC',
+    14: 'OFPMP_TABLE_DESC',
+    15: 'OFPMP_QUEUE_DESC',
+    16: 'OFPMP_FLOW_MONITOR',
+    65535: 'OFPST_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_switch_config_failed_code
+OFPSCFC_BAD_FLAGS = 0
+OFPSCFC_BAD_LEN = 1
+OFPSCFC_EPERM = 2
+
+ofp_switch_config_failed_code_map = {
+    0: 'OFPSCFC_BAD_FLAGS',
+    1: 'OFPSCFC_BAD_LEN',
+    2: 'OFPSCFC_EPERM',
+}
+
+# Identifiers from group ofp_table
+OFPTT_MAX = 254
+OFPTT_ALL = 255
+
+ofp_table_map = {
+    254: 'OFPTT_MAX',
+    255: 'OFPTT_ALL',
+}
+
+# Identifiers from group ofp_table_config
+OFPTC_DEPRECATED_MASK = 3
+OFPTC_EVICTION = 4
+OFPTC_VACANCY_EVENTS = 8
+
+ofp_table_config_map = {
+    3: 'OFPTC_DEPRECATED_MASK',
+    4: 'OFPTC_EVICTION',
+    8: 'OFPTC_VACANCY_EVENTS',
+}
+
+# Identifiers from group ofp_table_feature_prop_type
+OFPTFPT_INSTRUCTIONS = 0
+OFPTFPT_INSTRUCTIONS_MISS = 1
+OFPTFPT_NEXT_TABLES = 2
+OFPTFPT_NEXT_TABLES_MISS = 3
+OFPTFPT_WRITE_ACTIONS = 4
+OFPTFPT_WRITE_ACTIONS_MISS = 5
+OFPTFPT_APPLY_ACTIONS = 6
+OFPTFPT_APPLY_ACTIONS_MISS = 7
+OFPTFPT_MATCH = 8
+OFPTFPT_WILDCARDS = 10
+OFPTFPT_WRITE_SETFIELD = 12
+OFPTFPT_WRITE_SETFIELD_MISS = 13
+OFPTFPT_APPLY_SETFIELD = 14
+OFPTFPT_APPLY_SETFIELD_MISS = 15
+OFPTFPT_TABLE_SYNC_FROM = 16
+OFPTFPT_EXPERIMENTER = 65534
+OFPTFPT_EXPERIMENTER_MISS = 65535
+
+ofp_table_feature_prop_type_map = {
+    0: 'OFPTFPT_INSTRUCTIONS',
+    1: 'OFPTFPT_INSTRUCTIONS_MISS',
+    2: 'OFPTFPT_NEXT_TABLES',
+    3: 'OFPTFPT_NEXT_TABLES_MISS',
+    4: 'OFPTFPT_WRITE_ACTIONS',
+    5: 'OFPTFPT_WRITE_ACTIONS_MISS',
+    6: 'OFPTFPT_APPLY_ACTIONS',
+    7: 'OFPTFPT_APPLY_ACTIONS_MISS',
+    8: 'OFPTFPT_MATCH',
+    10: 'OFPTFPT_WILDCARDS',
+    12: 'OFPTFPT_WRITE_SETFIELD',
+    13: 'OFPTFPT_WRITE_SETFIELD_MISS',
+    14: 'OFPTFPT_APPLY_SETFIELD',
+    15: 'OFPTFPT_APPLY_SETFIELD_MISS',
+    16: 'OFPTFPT_TABLE_SYNC_FROM',
+    65534: 'OFPTFPT_EXPERIMENTER',
+    65535: 'OFPTFPT_EXPERIMENTER_MISS',
+}
+
+# Identifiers from group ofp_table_features_failed_code
+OFPTFFC_BAD_TABLE = 0
+OFPTFFC_BAD_METADATA = 1
+OFPTFFC_EPERM = 5
+
+ofp_table_features_failed_code_map = {
+    0: 'OFPTFFC_BAD_TABLE',
+    1: 'OFPTFFC_BAD_METADATA',
+    5: 'OFPTFFC_EPERM',
+}
+
+# Identifiers from group ofp_table_mod_failed_code
+OFPTMFC_BAD_TABLE = 0
+OFPTMFC_BAD_CONFIG = 1
+OFPTMFC_EPERM = 2
+
+ofp_table_mod_failed_code_map = {
+    0: 'OFPTMFC_BAD_TABLE',
+    1: 'OFPTMFC_BAD_CONFIG',
+    2: 'OFPTMFC_EPERM',
+}
+
+# Identifiers from group ofp_table_mod_prop_eviction_flag
+OFPTMPEF_OTHER = 1
+OFPTMPEF_IMPORTANCE = 2
+OFPTMPEF_LIFETIME = 4
+
+ofp_table_mod_prop_eviction_flag_map = {
+    1: 'OFPTMPEF_OTHER',
+    2: 'OFPTMPEF_IMPORTANCE',
+    4: 'OFPTMPEF_LIFETIME',
+}
+
+# Identifiers from group ofp_table_reason
+OFPTR_VACANCY_DOWN = 3
+OFPTR_VACANCY_UP = 4
+
+ofp_table_reason_map = {
+    3: 'OFPTR_VACANCY_DOWN',
+    4: 'OFPTR_VACANCY_UP',
+}
+
+# Identifiers from group ofp_type
+OFPT_HELLO = 0
+OFPT_ERROR = 1
+OFPT_ECHO_REQUEST = 2
+OFPT_ECHO_REPLY = 3
+OFPT_EXPERIMENTER = 4
+OFPT_FEATURES_REQUEST = 5
+OFPT_FEATURES_REPLY = 6
+OFPT_GET_CONFIG_REQUEST = 7
+OFPT_GET_CONFIG_REPLY = 8
+OFPT_SET_CONFIG = 9
+OFPT_PACKET_IN = 10
+OFPT_FLOW_REMOVED = 11
+OFPT_PORT_STATUS = 12
+OFPT_PACKET_OUT = 13
+OFPT_FLOW_MOD = 14
+OFPT_GROUP_MOD = 15
+OFPT_PORT_MOD = 16
+OFPT_TABLE_MOD = 17
+OFPT_STATS_REQUEST = 18
+OFPT_STATS_REPLY = 19
+OFPT_BARRIER_REQUEST = 20
+OFPT_BARRIER_REPLY = 21
+OFPT_ROLE_REQUEST = 24
+OFPT_ROLE_REPLY = 25
+OFPT_GET_ASYNC_REQUEST = 26
+OFPT_GET_ASYNC_REPLY = 27
+OFPT_SET_ASYNC = 28
+OFPT_METER_MOD = 29
+OFPT_ROLE_STATUS = 30
+OFPT_TABLE_STATUS = 31
+OFPT_REQUESTFORWARD = 32
+OFPT_BUNDLE_CONTROL = 33
+OFPT_BUNDLE_ADD_MESSAGE = 34
+
+ofp_type_map = {
+    0: 'OFPT_HELLO',
+    1: 'OFPT_ERROR',
+    2: 'OFPT_ECHO_REQUEST',
+    3: 'OFPT_ECHO_REPLY',
+    4: 'OFPT_EXPERIMENTER',
+    5: 'OFPT_FEATURES_REQUEST',
+    6: 'OFPT_FEATURES_REPLY',
+    7: 'OFPT_GET_CONFIG_REQUEST',
+    8: 'OFPT_GET_CONFIG_REPLY',
+    9: 'OFPT_SET_CONFIG',
+    10: 'OFPT_PACKET_IN',
+    11: 'OFPT_FLOW_REMOVED',
+    12: 'OFPT_PORT_STATUS',
+    13: 'OFPT_PACKET_OUT',
+    14: 'OFPT_FLOW_MOD',
+    15: 'OFPT_GROUP_MOD',
+    16: 'OFPT_PORT_MOD',
+    17: 'OFPT_TABLE_MOD',
+    18: 'OFPT_STATS_REQUEST',
+    19: 'OFPT_STATS_REPLY',
+    20: 'OFPT_BARRIER_REQUEST',
+    21: 'OFPT_BARRIER_REPLY',
+    24: 'OFPT_ROLE_REQUEST',
+    25: 'OFPT_ROLE_REPLY',
+    26: 'OFPT_GET_ASYNC_REQUEST',
+    27: 'OFPT_GET_ASYNC_REPLY',
+    28: 'OFPT_SET_ASYNC',
+    29: 'OFPT_METER_MOD',
+    30: 'OFPT_ROLE_STATUS',
+    31: 'OFPT_TABLE_STATUS',
+    32: 'OFPT_REQUESTFORWARD',
+    33: 'OFPT_BUNDLE_CONTROL',
+    34: 'OFPT_BUNDLE_ADD_MESSAGE',
+}
+
+# Identifiers from group ofp_vlan_id
+OFPVID_NONE = 0
+OFPVID_PRESENT = 4096
+
+ofp_vlan_id_map = {
+    0: 'OFPVID_NONE',
+    4096: 'OFPVID_PRESENT',
+}
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/instruction.py b/Fabric/Utilities/src/python/loxi/of14/instruction.py
new file mode 100644
index 0000000..d478f71
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/instruction.py
@@ -0,0 +1,1123 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class instruction(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = instruction.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = instruction()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("instruction {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class apply_actions(instruction):
+    type = 4
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[4] = apply_actions
+
+class experimenter(instruction):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_arp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_arp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_arp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_arp_offload
+
+class bsn_auto_negotiation(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_auto_negotiation()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_auto_negotiation {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[11] = bsn_auto_negotiation
+
+class bsn_deny(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_deny()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_deny {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_deny
+
+class bsn_dhcp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_dhcp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_dhcp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_dhcp_offload
+
+class bsn_disable_l3(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_l3()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_l3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[13] = bsn_disable_l3
+
+class bsn_disable_src_mac_check(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 0
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_src_mac_check()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 0)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_src_mac_check {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[0] = bsn_disable_src_mac_check
+
+class bsn_disable_vlan_counters(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_vlan_counters()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_vlan_counters {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[9] = bsn_disable_vlan_counters
+
+class bsn_internal_priority(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_internal_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_internal_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[12] = bsn_internal_priority
+
+class bsn_packet_of_death(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_packet_of_death()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_packet_of_death {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[6] = bsn_packet_of_death
+
+class bsn_permit(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_permit()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_permit {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_permit
+
+class bsn_prioritize_pdus(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_prioritize_pdus()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_prioritize_pdus {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[7] = bsn_prioritize_pdus
+
+class bsn_require_vlan_xlate(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_require_vlan_xlate()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_require_vlan_xlate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[8] = bsn_require_vlan_xlate
+
+class bsn_span_destination(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_span_destination()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_span_destination {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[10] = bsn_span_destination
+
+class clear_actions(instruction):
+    type = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = clear_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("clear_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[5] = clear_actions
+
+class goto_table(instruction):
+    type = 1
+
+    def __init__(self, table_id=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = goto_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("goto_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[1] = goto_table
+
+class meter(instruction):
+    type = 6
+
+    def __init__(self, meter_id=None):
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.meter_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.meter_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.meter_id != other.meter_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[6] = meter
+
+class write_actions(instruction):
+    type = 3
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[3] = write_actions
+
+class write_metadata(instruction):
+    type = 2
+
+    def __init__(self, metadata=None, metadata_mask=None):
+        if metadata != None:
+            self.metadata = metadata
+        else:
+            self.metadata = 0
+        if metadata_mask != None:
+            self.metadata_mask = metadata_mask
+        else:
+            self.metadata_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.metadata))
+        packed.append(struct.pack("!Q", self.metadata_mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_metadata()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.metadata = reader.read("!Q")[0]
+        obj.metadata_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.metadata != other.metadata: return False
+        if self.metadata_mask != other.metadata_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("metadata = ");
+                q.text("%#x" % self.metadata)
+                q.text(","); q.breakable()
+                q.text("metadata_mask = ");
+                q.text("%#x" % self.metadata_mask)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[2] = write_metadata
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/instruction_id.py b/Fabric/Utilities/src/python/loxi/of14/instruction_id.py
new file mode 100644
index 0000000..1e3184d
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/instruction_id.py
@@ -0,0 +1,1014 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class instruction_id(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = instruction_id.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = instruction_id()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("instruction_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class apply_actions(instruction_id):
+    type = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[4] = apply_actions
+
+class experimenter(instruction_id):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_arp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_arp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_arp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_arp_offload
+
+class bsn_auto_negotiation(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_auto_negotiation()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_auto_negotiation {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[11] = bsn_auto_negotiation
+
+class bsn_deny(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_deny()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_deny {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_deny
+
+class bsn_dhcp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_dhcp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_dhcp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_dhcp_offload
+
+class bsn_disable_l3(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_l3()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_l3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[13] = bsn_disable_l3
+
+class bsn_disable_src_mac_check(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 0
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_src_mac_check()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 0)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_src_mac_check {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[0] = bsn_disable_src_mac_check
+
+class bsn_disable_vlan_counters(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_vlan_counters()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_vlan_counters {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[9] = bsn_disable_vlan_counters
+
+class bsn_internal_priority(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_internal_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_internal_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[12] = bsn_internal_priority
+
+class bsn_packet_of_death(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_packet_of_death()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_packet_of_death {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[6] = bsn_packet_of_death
+
+class bsn_permit(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_permit()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_permit {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_permit
+
+class bsn_prioritize_pdus(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_prioritize_pdus()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_prioritize_pdus {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[7] = bsn_prioritize_pdus
+
+class bsn_require_vlan_xlate(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_require_vlan_xlate()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_require_vlan_xlate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[8] = bsn_require_vlan_xlate
+
+class bsn_span_destination(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_span_destination()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_span_destination {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[10] = bsn_span_destination
+
+class clear_actions(instruction_id):
+    type = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = clear_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("clear_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[5] = clear_actions
+
+class goto_table(instruction_id):
+    type = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = goto_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("goto_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[1] = goto_table
+
+class meter(instruction_id):
+    type = 6
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[6] = meter
+
+class write_actions(instruction_id):
+    type = 3
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[3] = write_actions
+
+class write_metadata(instruction_id):
+    type = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_metadata()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[2] = write_metadata
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/message.py b/Fabric/Utilities/src/python/loxi/of14/message.py
new file mode 100644
index 0000000..c285bb7
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/message.py
@@ -0,0 +1,16078 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class message(loxi.OFObject):
+    subtypes = {}
+
+    version = 5
+
+    def __init__(self, type=None, xid=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 1)
+        subclass = message.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = message()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        obj.type = reader.read("!B")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("message {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+
+class stats_reply(message):
+    subtypes = {}
+
+    version = 5
+    type = 19
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[19] = stats_reply
+
+class aggregate_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, packet_count=None, byte_count=None, flow_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if flow_count != None:
+            self.flow_count = flow_count
+        else:
+            self.flow_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(struct.pack("!L", self.flow_count))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.flow_count = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.flow_count != other.flow_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("flow_count = ");
+                q.text("%#x" % self.flow_count)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[2] = aggregate_stats_reply
+
+class stats_request(message):
+    subtypes = {}
+
+    version = 5
+    type = 18
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[18] = stats_request
+
+class aggregate_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[2] = aggregate_stats_request
+
+class error_msg(message):
+    subtypes = {}
+
+    version = 5
+    type = 1
+
+    def __init__(self, xid=None, err_type=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if err_type != None:
+            self.err_type = err_type
+        else:
+            self.err_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = error_msg.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.err_type = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.err_type != other.err_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[1] = error_msg
+
+class async_config_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 15
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = async_config_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 15)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_config_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[15] = async_config_failed_error_msg
+
+class async_get_reply(message):
+    version = 5
+    type = 27
+
+    def __init__(self, xid=None, properties=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = async_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 27)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.async_config_prop.async_config_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[27] = async_get_reply
+
+class async_get_request(message):
+    version = 5
+    type = 26
+
+    def __init__(self, xid=None, properties=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = async_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 26)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.async_config_prop.async_config_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[26] = async_get_request
+
+class async_set(message):
+    version = 5
+    type = 28
+
+    def __init__(self, xid=None, properties=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = async_set()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 28)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.async_config_prop.async_config_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_set {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[28] = async_set
+
+class bad_action_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 2
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_action_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 2)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_action_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[2] = bad_action_error_msg
+
+class bad_instruction_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 3
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_instruction_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 3)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_instruction_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[3] = bad_instruction_error_msg
+
+class bad_match_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 4
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_match_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 4)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_match_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[4] = bad_match_error_msg
+
+class bad_property_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 14
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_property_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 14)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_property_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[14] = bad_property_error_msg
+
+class bad_request_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 1
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_request_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 1)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_request_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[1] = bad_request_error_msg
+
+class barrier_reply(message):
+    version = 5
+    type = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 21)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[21] = barrier_reply
+
+class barrier_request(message):
+    version = 5
+    type = 20
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 20)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[20] = barrier_request
+
+class experimenter(message):
+    subtypes = {}
+
+    version = 5
+    type = 4
+
+    def __init__(self, xid=None, experimenter=None, subtype=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[4] = experimenter
+
+class bsn_header(experimenter):
+    subtypes = {}
+
+    version = 5
+    type = 4
+    experimenter = 6035143
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = bsn_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn_header
+
+class bsn_arp_idle(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 60
+
+    def __init__(self, xid=None, vlan_vid=None, ipv4_addr=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        if ipv4_addr != None:
+            self.ipv4_addr = ipv4_addr
+        else:
+            self.ipv4_addr = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.ipv4_addr))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_arp_idle()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 60)
+        obj.vlan_vid = reader.read("!H")[0]
+        reader.skip(2)
+        obj.ipv4_addr = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vlan_vid != other.vlan_vid: return False
+        if self.ipv4_addr != other.ipv4_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_arp_idle {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+                q.text(","); q.breakable()
+                q.text("ipv4_addr = ");
+                q.text(util.pretty_ipv4(self.ipv4_addr))
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[60] = bsn_arp_idle
+
+class bsn_bw_clear_data_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 22
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 22)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[22] = bsn_bw_clear_data_reply
+
+class bsn_bw_clear_data_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 21)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[21] = bsn_bw_clear_data_request
+
+class bsn_bw_enable_get_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 20
+
+    def __init__(self, xid=None, enabled=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enabled))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 20)
+        obj.enabled = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[20] = bsn_bw_enable_get_reply
+
+class bsn_bw_enable_get_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 19
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 19)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[19] = bsn_bw_enable_get_request
+
+class bsn_bw_enable_set_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 23
+
+    def __init__(self, xid=None, enable=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 23)
+        obj.enable = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[23] = bsn_bw_enable_set_reply
+
+class bsn_bw_enable_set_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 18
+
+    def __init__(self, xid=None, enable=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 18)
+        obj.enable = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[18] = bsn_bw_enable_set_request
+
+class bsn_controller_connections_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 57
+
+    def __init__(self, xid=None, connections=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if connections != None:
+            self.connections = connections
+        else:
+            self.connections = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.connections))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_controller_connections_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 57)
+        obj.connections = loxi.generic_util.unpack_list(reader, ofp.common.bsn_controller_connection.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.connections != other.connections: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_controller_connections_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("connections = ");
+                q.pp(self.connections)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[57] = bsn_controller_connections_reply
+
+class bsn_controller_connections_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 56
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_controller_connections_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 56)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_controller_connections_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[56] = bsn_controller_connections_request
+
+class experimenter_stats_reply(stats_reply):
+    subtypes = {}
+
+    version = 5
+    type = 19
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[65535] = experimenter_stats_reply
+
+class bsn_stats_reply(experimenter_stats_reply):
+    subtypes = {}
+
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_reply.subtypes[6035143] = bsn_stats_reply
+
+class bsn_debug_counter_desc_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_debug_counter_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[13] = bsn_debug_counter_desc_stats_reply
+
+class experimenter_stats_request(stats_request):
+    subtypes = {}
+
+    version = 5
+    type = 18
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[65535] = experimenter_stats_request
+
+class bsn_stats_request(experimenter_stats_request):
+    subtypes = {}
+
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_request.subtypes[6035143] = bsn_stats_request
+
+class bsn_debug_counter_desc_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[13] = bsn_debug_counter_desc_stats_request
+
+class bsn_debug_counter_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_debug_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[12] = bsn_debug_counter_stats_reply
+
+class bsn_debug_counter_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[12] = bsn_debug_counter_stats_request
+
+class bsn_flow_checksum_bucket_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_checksum_bucket_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_flow_checksum_bucket_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_checksum_bucket_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[10] = bsn_flow_checksum_bucket_stats_reply
+
+class bsn_flow_checksum_bucket_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, flags=None, table_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.table_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_checksum_bucket_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.table_id = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_checksum_bucket_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[10] = bsn_flow_checksum_bucket_stats_request
+
+class bsn_flow_idle(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 40
+
+    def __init__(self, xid=None, cookie=None, priority=None, table_id=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 5)
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 40)
+        obj.cookie = reader.read("!Q")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(5)
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.priority != other.priority: return False
+        if self.table_id != other.table_id: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[40] = bsn_flow_idle
+
+class bsn_flow_idle_enable_get_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 39
+
+    def __init__(self, xid=None, enabled=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enabled))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 39)
+        obj.enabled = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[39] = bsn_flow_idle_enable_get_reply
+
+class bsn_flow_idle_enable_get_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 38
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 38)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[38] = bsn_flow_idle_enable_get_request
+
+class bsn_flow_idle_enable_set_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 37
+
+    def __init__(self, xid=None, enable=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_set_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 37)
+        obj.enable = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_set_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[37] = bsn_flow_idle_enable_set_reply
+
+class bsn_flow_idle_enable_set_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 36
+
+    def __init__(self, xid=None, enable=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_set_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 36)
+        obj.enable = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_set_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[36] = bsn_flow_idle_enable_set_request
+
+class bsn_generic_async(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 68
+
+    def __init__(self, xid=None, name=None, tlvs=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if tlvs != None:
+            self.tlvs = tlvs
+        else:
+            self.tlvs = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!64s", self.name))
+        packed.append(loxi.generic_util.pack_list(self.tlvs))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generic_async()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 68)
+        obj.name = reader.read("!64s")[0].rstrip("\x00")
+        obj.tlvs = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.name != other.name: return False
+        if self.tlvs != other.tlvs: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generic_async {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("tlvs = ");
+                q.pp(self.tlvs)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[68] = bsn_generic_async
+
+class bsn_generic_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generic_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_generic_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generic_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[16] = bsn_generic_stats_reply
+
+class bsn_generic_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, flags=None, name=None, tlvs=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if tlvs != None:
+            self.tlvs = tlvs
+        else:
+            self.tlvs = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!64s", self.name))
+        packed.append(loxi.generic_util.pack_list(self.tlvs))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generic_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.name = reader.read("!64s")[0].rstrip("\x00")
+        obj.tlvs = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.name != other.name: return False
+        if self.tlvs != other.tlvs: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generic_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("tlvs = ");
+                q.pp(self.tlvs)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[16] = bsn_generic_stats_request
+
+class bsn_gentable_bucket_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_bucket_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_bucket_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_bucket_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[5] = bsn_gentable_bucket_stats_reply
+
+class bsn_gentable_bucket_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, flags=None, table_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_bucket_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.table_id = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_bucket_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[5] = bsn_gentable_bucket_stats_request
+
+class bsn_gentable_clear_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 49
+
+    def __init__(self, xid=None, table_id=None, deleted_count=None, error_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if deleted_count != None:
+            self.deleted_count = deleted_count
+        else:
+            self.deleted_count = 0
+        if error_count != None:
+            self.error_count = error_count
+        else:
+            self.error_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.deleted_count))
+        packed.append(struct.pack("!L", self.error_count))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_clear_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 49)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.deleted_count = reader.read("!L")[0]
+        obj.error_count = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.deleted_count != other.deleted_count: return False
+        if self.error_count != other.error_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_clear_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("deleted_count = ");
+                q.text("%#x" % self.deleted_count)
+                q.text(","); q.breakable()
+                q.text("error_count = ");
+                q.text("%#x" % self.error_count)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[49] = bsn_gentable_clear_reply
+
+class bsn_gentable_clear_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 48
+
+    def __init__(self, xid=None, table_id=None, checksum=None, checksum_mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if checksum_mask != None:
+            self.checksum_mask = checksum_mask
+        else:
+            self.checksum_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(util.pack_checksum_128(self.checksum_mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_clear_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 48)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.checksum_mask = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.checksum_mask != other.checksum_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_clear_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("checksum_mask = ");
+                q.pp(self.checksum_mask)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[48] = bsn_gentable_clear_request
+
+class bsn_gentable_desc_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[4] = bsn_gentable_desc_stats_reply
+
+class bsn_gentable_desc_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[4] = bsn_gentable_desc_stats_request
+
+class bsn_gentable_entry_add(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 46
+
+    def __init__(self, xid=None, table_id=None, checksum=None, key=None, value=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        if value != None:
+            self.value = value
+        else:
+            self.value = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(struct.pack("!H", 0)) # placeholder for key_length at index 7
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        packed[7] = struct.pack("!H", len(packed[-1]))
+        packed.append(loxi.generic_util.pack_list(self.value))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 46)
+        obj.table_id = reader.read("!H")[0]
+        _key_length = reader.read("!H")[0]
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.key = loxi.generic_util.unpack_list(reader.slice(_key_length), ofp.bsn_tlv.bsn_tlv.unpack)
+        obj.value = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.key != other.key: return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+                q.text(","); q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[46] = bsn_gentable_entry_add
+
+class bsn_gentable_entry_delete(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 47
+
+    def __init__(self, xid=None, table_id=None, key=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 47)
+        obj.table_id = reader.read("!H")[0]
+        obj.key = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.key != other.key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[47] = bsn_gentable_entry_delete
+
+class bsn_gentable_entry_desc_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_entry_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[2] = bsn_gentable_entry_desc_stats_reply
+
+class bsn_gentable_entry_desc_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, xid=None, flags=None, table_id=None, checksum=None, checksum_mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if checksum_mask != None:
+            self.checksum_mask = checksum_mask
+        else:
+            self.checksum_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(util.pack_checksum_128(self.checksum_mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.checksum_mask = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.checksum_mask != other.checksum_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("checksum_mask = ");
+                q.pp(self.checksum_mask)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[2] = bsn_gentable_entry_desc_stats_request
+
+class bsn_gentable_entry_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_entry_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[3] = bsn_gentable_entry_stats_reply
+
+class bsn_gentable_entry_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, flags=None, table_id=None, checksum=None, checksum_mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if checksum_mask != None:
+            self.checksum_mask = checksum_mask
+        else:
+            self.checksum_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(util.pack_checksum_128(self.checksum_mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.checksum_mask = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.checksum_mask != other.checksum_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("checksum_mask = ");
+                q.pp(self.checksum_mask)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[3] = bsn_gentable_entry_stats_request
+
+class bsn_gentable_set_buckets_size(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 50
+
+    def __init__(self, xid=None, table_id=None, buckets_size=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if buckets_size != None:
+            self.buckets_size = buckets_size
+        else:
+            self.buckets_size = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.buckets_size))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_set_buckets_size()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 50)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.buckets_size = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.buckets_size != other.buckets_size: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_set_buckets_size {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("buckets_size = ");
+                q.text("%#x" % self.buckets_size)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[50] = bsn_gentable_set_buckets_size
+
+class bsn_gentable_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[7] = bsn_gentable_stats_reply
+
+class bsn_gentable_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[7] = bsn_gentable_stats_request
+
+class bsn_get_interfaces_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, interfaces=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if interfaces != None:
+            self.interfaces = interfaces
+        else:
+            self.interfaces = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.interfaces))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.interfaces = loxi.generic_util.unpack_list(reader, ofp.common.bsn_interface.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.interfaces != other.interfaces: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("interfaces = ");
+                q.pp(self.interfaces)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[10] = bsn_get_interfaces_reply
+
+class bsn_get_interfaces_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[9] = bsn_get_interfaces_request
+
+class bsn_get_mirroring_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[5] = bsn_get_mirroring_reply
+
+class bsn_get_mirroring_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[4] = bsn_get_mirroring_request
+
+class bsn_get_switch_pipeline_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 52
+
+    def __init__(self, xid=None, pipeline=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if pipeline != None:
+            self.pipeline = pipeline
+        else:
+            self.pipeline = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!256s", self.pipeline))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_switch_pipeline_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 52)
+        obj.pipeline = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.pipeline != other.pipeline: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_switch_pipeline_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("pipeline = ");
+                q.pp(self.pipeline)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[52] = bsn_get_switch_pipeline_reply
+
+class bsn_get_switch_pipeline_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 51
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_switch_pipeline_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 51)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_switch_pipeline_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[51] = bsn_get_switch_pipeline_request
+
+class bsn_image_desc_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 14
+
+    def __init__(self, xid=None, flags=None, image_checksum=None, startup_config_checksum=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if image_checksum != None:
+            self.image_checksum = image_checksum
+        else:
+            self.image_checksum = ""
+        if startup_config_checksum != None:
+            self.startup_config_checksum = startup_config_checksum
+        else:
+            self.startup_config_checksum = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!256s", self.image_checksum))
+        packed.append(struct.pack("!256s", self.startup_config_checksum))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_image_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 14)
+        obj.image_checksum = reader.read("!256s")[0].rstrip("\x00")
+        obj.startup_config_checksum = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.image_checksum != other.image_checksum: return False
+        if self.startup_config_checksum != other.startup_config_checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_image_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("image_checksum = ");
+                q.pp(self.image_checksum)
+                q.text(","); q.breakable()
+                q.text("startup_config_checksum = ");
+                q.pp(self.startup_config_checksum)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[14] = bsn_image_desc_stats_reply
+
+class bsn_image_desc_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 14
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_image_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 14)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_image_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[14] = bsn_image_desc_stats_request
+
+class bsn_lacp_convergence_notif(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 43
+
+    def __init__(self, xid=None, convergence_status=None, port_no=None, actor_sys_priority=None, actor_sys_mac=None, actor_port_priority=None, actor_port_num=None, actor_key=None, partner_sys_priority=None, partner_sys_mac=None, partner_port_priority=None, partner_port_num=None, partner_key=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if convergence_status != None:
+            self.convergence_status = convergence_status
+        else:
+            self.convergence_status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if actor_sys_priority != None:
+            self.actor_sys_priority = actor_sys_priority
+        else:
+            self.actor_sys_priority = 0
+        if actor_sys_mac != None:
+            self.actor_sys_mac = actor_sys_mac
+        else:
+            self.actor_sys_mac = [0,0,0,0,0,0]
+        if actor_port_priority != None:
+            self.actor_port_priority = actor_port_priority
+        else:
+            self.actor_port_priority = 0
+        if actor_port_num != None:
+            self.actor_port_num = actor_port_num
+        else:
+            self.actor_port_num = 0
+        if actor_key != None:
+            self.actor_key = actor_key
+        else:
+            self.actor_key = 0
+        if partner_sys_priority != None:
+            self.partner_sys_priority = partner_sys_priority
+        else:
+            self.partner_sys_priority = 0
+        if partner_sys_mac != None:
+            self.partner_sys_mac = partner_sys_mac
+        else:
+            self.partner_sys_mac = [0,0,0,0,0,0]
+        if partner_port_priority != None:
+            self.partner_port_priority = partner_port_priority
+        else:
+            self.partner_port_priority = 0
+        if partner_port_num != None:
+            self.partner_port_num = partner_port_num
+        else:
+            self.partner_port_num = 0
+        if partner_key != None:
+            self.partner_key = partner_key
+        else:
+            self.partner_key = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.convergence_status))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!H", self.actor_sys_priority))
+        packed.append(struct.pack("!6B", *self.actor_sys_mac))
+        packed.append(struct.pack("!H", self.actor_port_priority))
+        packed.append(struct.pack("!H", self.actor_port_num))
+        packed.append(struct.pack("!H", self.actor_key))
+        packed.append(struct.pack("!H", self.partner_sys_priority))
+        packed.append(struct.pack("!6B", *self.partner_sys_mac))
+        packed.append(struct.pack("!H", self.partner_port_priority))
+        packed.append(struct.pack("!H", self.partner_port_num))
+        packed.append(struct.pack("!H", self.partner_key))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_convergence_notif()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 43)
+        obj.convergence_status = reader.read("!B")[0]
+        reader.skip(3)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.actor_sys_priority = reader.read("!H")[0]
+        obj.actor_sys_mac = list(reader.read('!6B'))
+        obj.actor_port_priority = reader.read("!H")[0]
+        obj.actor_port_num = reader.read("!H")[0]
+        obj.actor_key = reader.read("!H")[0]
+        obj.partner_sys_priority = reader.read("!H")[0]
+        obj.partner_sys_mac = list(reader.read('!6B'))
+        obj.partner_port_priority = reader.read("!H")[0]
+        obj.partner_port_num = reader.read("!H")[0]
+        obj.partner_key = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.convergence_status != other.convergence_status: return False
+        if self.port_no != other.port_no: return False
+        if self.actor_sys_priority != other.actor_sys_priority: return False
+        if self.actor_sys_mac != other.actor_sys_mac: return False
+        if self.actor_port_priority != other.actor_port_priority: return False
+        if self.actor_port_num != other.actor_port_num: return False
+        if self.actor_key != other.actor_key: return False
+        if self.partner_sys_priority != other.partner_sys_priority: return False
+        if self.partner_sys_mac != other.partner_sys_mac: return False
+        if self.partner_port_priority != other.partner_port_priority: return False
+        if self.partner_port_num != other.partner_port_num: return False
+        if self.partner_key != other.partner_key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_convergence_notif {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("convergence_status = ");
+                q.text("%#x" % self.convergence_status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("actor_sys_priority = ");
+                q.text("%#x" % self.actor_sys_priority)
+                q.text(","); q.breakable()
+                q.text("actor_sys_mac = ");
+                q.text(util.pretty_mac(self.actor_sys_mac))
+                q.text(","); q.breakable()
+                q.text("actor_port_priority = ");
+                q.text("%#x" % self.actor_port_priority)
+                q.text(","); q.breakable()
+                q.text("actor_port_num = ");
+                q.text("%#x" % self.actor_port_num)
+                q.text(","); q.breakable()
+                q.text("actor_key = ");
+                q.text("%#x" % self.actor_key)
+                q.text(","); q.breakable()
+                q.text("partner_sys_priority = ");
+                q.text("%#x" % self.partner_sys_priority)
+                q.text(","); q.breakable()
+                q.text("partner_sys_mac = ");
+                q.text(util.pretty_mac(self.partner_sys_mac))
+                q.text(","); q.breakable()
+                q.text("partner_port_priority = ");
+                q.text("%#x" % self.partner_port_priority)
+                q.text(","); q.breakable()
+                q.text("partner_port_num = ");
+                q.text("%#x" % self.partner_port_num)
+                q.text(","); q.breakable()
+                q.text("partner_key = ");
+                q.text("%#x" % self.partner_key)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[43] = bsn_lacp_convergence_notif
+
+class bsn_lacp_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_lacp_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[1] = bsn_lacp_stats_reply
+
+class bsn_lacp_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[1] = bsn_lacp_stats_request
+
+class bsn_log(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 63
+
+    def __init__(self, xid=None, loglevel=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if loglevel != None:
+            self.loglevel = loglevel
+        else:
+            self.loglevel = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.loglevel))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_log()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 63)
+        obj.loglevel = reader.read("!B")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.loglevel != other.loglevel: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_log {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("loglevel = ");
+                q.text("%#x" % self.loglevel)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[63] = bsn_log
+
+class bsn_lua_command_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 66
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_command_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 66)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_command_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[66] = bsn_lua_command_reply
+
+class bsn_lua_command_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 65
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_command_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 65)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_command_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[65] = bsn_lua_command_request
+
+class bsn_lua_notification(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 67
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_notification()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 67)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_notification {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[67] = bsn_lua_notification
+
+class bsn_lua_upload(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 64
+
+    def __init__(self, xid=None, flags=None, filename=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if filename != None:
+            self.filename = filename
+        else:
+            self.filename = ""
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!64s", self.filename))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_upload()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 64)
+        obj.flags = reader.read("!H")[0]
+        obj.filename = reader.read("!64s")[0].rstrip("\x00")
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.filename != other.filename: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_upload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("filename = ");
+                q.pp(self.filename)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[64] = bsn_lua_upload
+
+class bsn_pdu_rx_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 34
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 34)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[34] = bsn_pdu_rx_reply
+
+class bsn_pdu_rx_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 33
+
+    def __init__(self, xid=None, timeout_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if timeout_ms != None:
+            self.timeout_ms = timeout_ms
+        else:
+            self.timeout_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.timeout_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 33)
+        obj.timeout_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.timeout_ms != other.timeout_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("timeout_ms = ");
+                q.text("%#x" % self.timeout_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[33] = bsn_pdu_rx_request
+
+class bsn_pdu_rx_timeout(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 35
+
+    def __init__(self, xid=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_timeout()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 35)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[35] = bsn_pdu_rx_timeout
+
+class bsn_pdu_tx_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 32
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 32)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[32] = bsn_pdu_tx_reply
+
+class bsn_pdu_tx_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 31
+
+    def __init__(self, xid=None, tx_interval_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if tx_interval_ms != None:
+            self.tx_interval_ms = tx_interval_ms
+        else:
+            self.tx_interval_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.tx_interval_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 31)
+        obj.tx_interval_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.tx_interval_ms != other.tx_interval_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("tx_interval_ms = ");
+                q.text("%#x" % self.tx_interval_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[31] = bsn_pdu_tx_request
+
+class bsn_port_counter_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_port_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_port_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_port_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[8] = bsn_port_counter_stats_reply
+
+class bsn_port_counter_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self, xid=None, flags=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_port_no(self.port_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_port_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        obj.port_no = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_port_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[8] = bsn_port_counter_stats_request
+
+class bsn_set_aux_cxns_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 59
+
+    def __init__(self, xid=None, num_aux=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if num_aux != None:
+            self.num_aux = num_aux
+        else:
+            self.num_aux = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.num_aux))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_aux_cxns_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 59)
+        obj.num_aux = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.num_aux != other.num_aux: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_aux_cxns_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("num_aux = ");
+                q.text("%#x" % self.num_aux)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[59] = bsn_set_aux_cxns_reply
+
+class bsn_set_aux_cxns_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 58
+
+    def __init__(self, xid=None, num_aux=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if num_aux != None:
+            self.num_aux = num_aux
+        else:
+            self.num_aux = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.num_aux))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_aux_cxns_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 58)
+        obj.num_aux = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.num_aux != other.num_aux: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_aux_cxns_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("num_aux = ");
+                q.text("%#x" % self.num_aux)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[58] = bsn_set_aux_cxns_request
+
+class bsn_set_lacp_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 42
+
+    def __init__(self, xid=None, status=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_lacp_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 42)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_lacp_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[42] = bsn_set_lacp_reply
+
+class bsn_set_lacp_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 41
+
+    def __init__(self, xid=None, enabled=None, port_no=None, actor_sys_priority=None, actor_sys_mac=None, actor_port_priority=None, actor_port_num=None, actor_key=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if actor_sys_priority != None:
+            self.actor_sys_priority = actor_sys_priority
+        else:
+            self.actor_sys_priority = 0
+        if actor_sys_mac != None:
+            self.actor_sys_mac = actor_sys_mac
+        else:
+            self.actor_sys_mac = [0,0,0,0,0,0]
+        if actor_port_priority != None:
+            self.actor_port_priority = actor_port_priority
+        else:
+            self.actor_port_priority = 0
+        if actor_port_num != None:
+            self.actor_port_num = actor_port_num
+        else:
+            self.actor_port_num = 0
+        if actor_key != None:
+            self.actor_key = actor_key
+        else:
+            self.actor_key = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.enabled))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!H", self.actor_sys_priority))
+        packed.append(struct.pack("!6B", *self.actor_sys_mac))
+        packed.append(struct.pack("!H", self.actor_port_priority))
+        packed.append(struct.pack("!H", self.actor_port_num))
+        packed.append(struct.pack("!H", self.actor_key))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_lacp_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 41)
+        obj.enabled = reader.read("!B")[0]
+        reader.skip(3)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.actor_sys_priority = reader.read("!H")[0]
+        obj.actor_sys_mac = list(reader.read('!6B'))
+        obj.actor_port_priority = reader.read("!H")[0]
+        obj.actor_port_num = reader.read("!H")[0]
+        obj.actor_key = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        if self.port_no != other.port_no: return False
+        if self.actor_sys_priority != other.actor_sys_priority: return False
+        if self.actor_sys_mac != other.actor_sys_mac: return False
+        if self.actor_port_priority != other.actor_port_priority: return False
+        if self.actor_port_num != other.actor_port_num: return False
+        if self.actor_key != other.actor_key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_lacp_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("actor_sys_priority = ");
+                q.text("%#x" % self.actor_sys_priority)
+                q.text(","); q.breakable()
+                q.text("actor_sys_mac = ");
+                q.text(util.pretty_mac(self.actor_sys_mac))
+                q.text(","); q.breakable()
+                q.text("actor_port_priority = ");
+                q.text("%#x" % self.actor_port_priority)
+                q.text(","); q.breakable()
+                q.text("actor_port_num = ");
+                q.text("%#x" % self.actor_port_num)
+                q.text(","); q.breakable()
+                q.text("actor_key = ");
+                q.text("%#x" % self.actor_key)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[41] = bsn_set_lacp_request
+
+class bsn_set_mirroring(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_mirroring()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_mirroring {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[3] = bsn_set_mirroring
+
+class bsn_set_pktin_suppression_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 25
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 25)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[25] = bsn_set_pktin_suppression_reply
+
+class bsn_set_pktin_suppression_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, enabled=None, idle_timeout=None, hard_timeout=None, priority=None, cookie=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.enabled))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!Q", self.cookie))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.enabled = reader.read("!B")[0]
+        reader.skip(1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.cookie = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.cookie != other.cookie: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[11] = bsn_set_pktin_suppression_request
+
+class bsn_set_switch_pipeline_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 54
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_switch_pipeline_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 54)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_switch_pipeline_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[54] = bsn_set_switch_pipeline_reply
+
+class bsn_set_switch_pipeline_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 53
+
+    def __init__(self, xid=None, pipeline=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if pipeline != None:
+            self.pipeline = pipeline
+        else:
+            self.pipeline = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!256s", self.pipeline))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_switch_pipeline_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 53)
+        obj.pipeline = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.pipeline != other.pipeline: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_switch_pipeline_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("pipeline = ");
+                q.pp(self.pipeline)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[53] = bsn_set_switch_pipeline_request
+
+class bsn_switch_pipeline_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_switch_pipeline_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_switch_pipeline_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_switch_pipeline_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[6] = bsn_switch_pipeline_stats_reply
+
+class bsn_switch_pipeline_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_switch_pipeline_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_switch_pipeline_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[6] = bsn_switch_pipeline_stats_request
+
+class bsn_table_checksum_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_checksum_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_table_checksum_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_checksum_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[11] = bsn_table_checksum_stats_reply
+
+class bsn_table_checksum_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_checksum_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_checksum_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[11] = bsn_table_checksum_stats_request
+
+class bsn_table_set_buckets_size(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 61
+
+    def __init__(self, xid=None, table_id=None, buckets_size=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if buckets_size != None:
+            self.buckets_size = buckets_size
+        else:
+            self.buckets_size = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.buckets_size))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_set_buckets_size()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 61)
+        reader.skip(1)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(2)
+        obj.buckets_size = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.buckets_size != other.buckets_size: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_set_buckets_size {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("buckets_size = ");
+                q.text("%#x" % self.buckets_size)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[61] = bsn_table_set_buckets_size
+
+class bsn_takeover(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 69
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_takeover()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 69)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_takeover {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[69] = bsn_takeover
+
+class bsn_time_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 45
+
+    def __init__(self, xid=None, time_ms=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if time_ms != None:
+            self.time_ms = time_ms
+        else:
+            self.time_ms = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!Q", self.time_ms))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_time_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 45)
+        obj.time_ms = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.time_ms != other.time_ms: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_time_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("time_ms = ");
+                q.text("%#x" % self.time_ms)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[45] = bsn_time_reply
+
+class bsn_time_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 44
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_time_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 44)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_time_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[44] = bsn_time_request
+
+class bsn_virtual_port_create_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, status=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.status = reader.read("!L")[0]
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[16] = bsn_virtual_port_create_reply
+
+class bsn_virtual_port_create_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, vport=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport != None:
+            self.vport = vport
+        else:
+            self.vport = ofp.bsn_vport()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.vport.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.vport = ofp.bsn_vport.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport != other.vport: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport = ");
+                q.pp(self.vport)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[15] = bsn_virtual_port_create_request
+
+class bsn_virtual_port_remove_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 26
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 26)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[26] = bsn_virtual_port_remove_reply
+
+class bsn_virtual_port_remove_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 17
+
+    def __init__(self, xid=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 17)
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[17] = bsn_virtual_port_remove_request
+
+class bsn_vlan_counter_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_vlan_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[9] = bsn_vlan_counter_stats_reply
+
+class bsn_vlan_counter_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None, flags=None, vlan_vid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.vlan_vid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        obj.vlan_vid = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.vlan_vid != other.vlan_vid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[9] = bsn_vlan_counter_stats_request
+
+class bsn_vrf_counter_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_vrf_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[15] = bsn_vrf_counter_stats_reply
+
+class bsn_vrf_counter_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, flags=None, vrf=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if vrf != None:
+            self.vrf = vrf
+        else:
+            self.vrf = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.vrf))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.vrf = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.vrf != other.vrf: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("vrf = ");
+                q.text("%#x" % self.vrf)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[15] = bsn_vrf_counter_stats_request
+
+class bundle_add_msg(message):
+    version = 5
+    type = 34
+
+    def __init__(self, xid=None, bundle_id=None, flags=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if bundle_id != None:
+            self.bundle_id = bundle_id
+        else:
+            self.bundle_id = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.bundle_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bundle_add_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 34)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.bundle_id = reader.read("!L")[0]
+        reader.skip(2)
+        obj.flags = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.bundle_id != other.bundle_id: return False
+        if self.flags != other.flags: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bundle_add_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("bundle_id = ");
+                q.text("%#x" % self.bundle_id)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[34] = bundle_add_msg
+
+class bundle_ctrl_msg(message):
+    version = 5
+    type = 33
+
+    def __init__(self, xid=None, bundle_id=None, bundle_ctrl_type=None, flags=None, properties=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if bundle_id != None:
+            self.bundle_id = bundle_id
+        else:
+            self.bundle_id = 0
+        if bundle_ctrl_type != None:
+            self.bundle_ctrl_type = bundle_ctrl_type
+        else:
+            self.bundle_ctrl_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.bundle_id))
+        packed.append(struct.pack("!H", self.bundle_ctrl_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bundle_ctrl_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 33)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.bundle_id = reader.read("!L")[0]
+        obj.bundle_ctrl_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.bundle_prop.bundle_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.bundle_id != other.bundle_id: return False
+        if self.bundle_ctrl_type != other.bundle_ctrl_type: return False
+        if self.flags != other.flags: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bundle_ctrl_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("bundle_id = ");
+                q.text("%#x" % self.bundle_id)
+                q.text(","); q.breakable()
+                q.text("bundle_ctrl_type = ");
+                q.text("%#x" % self.bundle_ctrl_type)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[33] = bundle_ctrl_msg
+
+class bundle_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 17
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bundle_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 17)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bundle_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[17] = bundle_failed_error_msg
+
+class desc_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None, mfr_desc=None, hw_desc=None, sw_desc=None, serial_num=None, dp_desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if mfr_desc != None:
+            self.mfr_desc = mfr_desc
+        else:
+            self.mfr_desc = ""
+        if hw_desc != None:
+            self.hw_desc = hw_desc
+        else:
+            self.hw_desc = ""
+        if sw_desc != None:
+            self.sw_desc = sw_desc
+        else:
+            self.sw_desc = ""
+        if serial_num != None:
+            self.serial_num = serial_num
+        else:
+            self.serial_num = ""
+        if dp_desc != None:
+            self.dp_desc = dp_desc
+        else:
+            self.dp_desc = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!256s", self.mfr_desc))
+        packed.append(struct.pack("!256s", self.hw_desc))
+        packed.append(struct.pack("!256s", self.sw_desc))
+        packed.append(struct.pack("!32s", self.serial_num))
+        packed.append(struct.pack("!256s", self.dp_desc))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.mfr_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.hw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.sw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.serial_num = reader.read("!32s")[0].rstrip("\x00")
+        obj.dp_desc = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.mfr_desc != other.mfr_desc: return False
+        if self.hw_desc != other.hw_desc: return False
+        if self.sw_desc != other.sw_desc: return False
+        if self.serial_num != other.serial_num: return False
+        if self.dp_desc != other.dp_desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("mfr_desc = ");
+                q.pp(self.mfr_desc)
+                q.text(","); q.breakable()
+                q.text("hw_desc = ");
+                q.pp(self.hw_desc)
+                q.text(","); q.breakable()
+                q.text("sw_desc = ");
+                q.pp(self.sw_desc)
+                q.text(","); q.breakable()
+                q.text("serial_num = ");
+                q.pp(self.serial_num)
+                q.text(","); q.breakable()
+                q.text("dp_desc = ");
+                q.pp(self.dp_desc)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[0] = desc_stats_reply
+
+class desc_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[0] = desc_stats_request
+
+class echo_reply(message):
+    version = 5
+    type = 3
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[3] = echo_reply
+
+class echo_request(message):
+    version = 5
+    type = 2
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[2] = echo_request
+
+class experimenter_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 65535
+
+    def __init__(self, xid=None, subtype=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = experimenter_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 65535)
+        obj.subtype = reader.read("!H")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("experimenter = ");
+                q.text("%#x" % self.experimenter)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[65535] = experimenter_error_msg
+
+class features_reply(message):
+    version = 5
+    type = 6
+
+    def __init__(self, xid=None, datapath_id=None, n_buffers=None, n_tables=None, auxiliary_id=None, capabilities=None, reserved=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if datapath_id != None:
+            self.datapath_id = datapath_id
+        else:
+            self.datapath_id = 0
+        if n_buffers != None:
+            self.n_buffers = n_buffers
+        else:
+            self.n_buffers = 0
+        if n_tables != None:
+            self.n_tables = n_tables
+        else:
+            self.n_tables = 0
+        if auxiliary_id != None:
+            self.auxiliary_id = auxiliary_id
+        else:
+            self.auxiliary_id = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if reserved != None:
+            self.reserved = reserved
+        else:
+            self.reserved = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.datapath_id))
+        packed.append(struct.pack("!L", self.n_buffers))
+        packed.append(struct.pack("!B", self.n_tables))
+        packed.append(struct.pack("!B", self.auxiliary_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.reserved))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.datapath_id = reader.read("!Q")[0]
+        obj.n_buffers = reader.read("!L")[0]
+        obj.n_tables = reader.read("!B")[0]
+        obj.auxiliary_id = reader.read("!B")[0]
+        reader.skip(2)
+        obj.capabilities = reader.read("!L")[0]
+        obj.reserved = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.datapath_id != other.datapath_id: return False
+        if self.n_buffers != other.n_buffers: return False
+        if self.n_tables != other.n_tables: return False
+        if self.auxiliary_id != other.auxiliary_id: return False
+        if self.capabilities != other.capabilities: return False
+        if self.reserved != other.reserved: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("datapath_id = ");
+                q.text("%#x" % self.datapath_id)
+                q.text(","); q.breakable()
+                q.text("n_buffers = ");
+                q.text("%#x" % self.n_buffers)
+                q.text(","); q.breakable()
+                q.text("n_tables = ");
+                q.text("%#x" % self.n_tables)
+                q.text(","); q.breakable()
+                q.text("auxiliary_id = ");
+                q.text("%#x" % self.auxiliary_id)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("reserved = ");
+                q.text("%#x" % self.reserved)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[6] = features_reply
+
+class features_request(message):
+    version = 5
+    type = 5
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[5] = features_request
+
+class flow_mod(message):
+    subtypes = {}
+
+    version = 5
+    type = 14
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, _command=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if _command != None:
+            self._command = _command
+        else:
+            self._command = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 25)
+        subclass = flow_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = flow_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj._command = util.unpack_fm_cmd(reader)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self._command != other._command: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[14] = flow_mod
+
+class flow_add(flow_mod):
+    version = 5
+    type = 14
+    _command = 0
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, importance=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if importance != None:
+            self.importance = importance
+        else:
+            self.importance = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.importance))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 0)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.importance = reader.read("!H")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.importance != other.importance: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("importance = ");
+                q.text("%#x" % self.importance)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[0] = flow_add
+
+class flow_delete(flow_mod):
+    version = 5
+    type = 14
+    _command = 3
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, importance=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if importance != None:
+            self.importance = importance
+        else:
+            self.importance = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.importance))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 3)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.importance = reader.read("!H")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.importance != other.importance: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("importance = ");
+                q.text("%#x" % self.importance)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[3] = flow_delete
+
+class flow_delete_strict(flow_mod):
+    version = 5
+    type = 14
+    _command = 4
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, importance=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if importance != None:
+            self.importance = importance
+        else:
+            self.importance = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.importance))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 4)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.importance = reader.read("!H")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.importance != other.importance: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("importance = ");
+                q.text("%#x" % self.importance)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[4] = flow_delete_strict
+
+class flow_mod_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 5
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 5)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[5] = flow_mod_failed_error_msg
+
+class flow_modify(flow_mod):
+    version = 5
+    type = 14
+    _command = 1
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, importance=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if importance != None:
+            self.importance = importance
+        else:
+            self.importance = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.importance))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.importance = reader.read("!H")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.importance != other.importance: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("importance = ");
+                q.text("%#x" % self.importance)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[1] = flow_modify
+
+class flow_modify_strict(flow_mod):
+    version = 5
+    type = 14
+    _command = 2
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, importance=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if importance != None:
+            self.importance = importance
+        else:
+            self.importance = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.importance))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 2)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.importance = reader.read("!H")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.importance != other.importance: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("importance = ");
+                q.text("%#x" % self.importance)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[2] = flow_modify_strict
+
+class flow_monitor_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 16
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_monitor_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 16)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_monitor_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[16] = flow_monitor_failed_error_msg
+
+class flow_removed(message):
+    version = 5
+    type = 11
+
+    def __init__(self, xid=None, cookie=None, priority=None, reason=None, table_id=None, duration_sec=None, duration_nsec=None, idle_timeout=None, hard_timeout=None, packet_count=None, byte_count=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_removed()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.priority != other.priority: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_removed {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[11] = flow_removed
+
+class flow_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.flow_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[1] = flow_stats_reply
+
+class flow_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[1] = flow_stats_request
+
+class get_config_reply(message):
+    version = 5
+    type = 8
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[8] = get_config_reply
+
+class get_config_request(message):
+    version = 5
+    type = 7
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[7] = get_config_request
+
+class group_mod(message):
+    subtypes = {}
+
+    version = 5
+    type = 15
+
+    def __init__(self, xid=None, command=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if command != None:
+            self.command = command
+        else:
+            self.command = 0
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = group_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = group_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.command = reader.read("!H")[0]
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.command != other.command: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[15] = group_mod
+
+class group_add(group_mod):
+    version = 5
+    type = 15
+    command = 0
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 0)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[0] = group_add
+
+class group_delete(group_mod):
+    version = 5
+    type = 15
+    command = 2
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[2] = group_delete
+
+class group_desc_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[7] = group_desc_stats_reply
+
+class group_desc_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[7] = group_desc_stats_request
+
+class group_features_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 8
+
+    def __init__(self, xid=None, flags=None, types=None, capabilities=None, max_groups_all=None, max_groups_select=None, max_groups_indirect=None, max_groups_ff=None, actions_all=None, actions_select=None, actions_indirect=None, actions_ff=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if types != None:
+            self.types = types
+        else:
+            self.types = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if max_groups_all != None:
+            self.max_groups_all = max_groups_all
+        else:
+            self.max_groups_all = 0
+        if max_groups_select != None:
+            self.max_groups_select = max_groups_select
+        else:
+            self.max_groups_select = 0
+        if max_groups_indirect != None:
+            self.max_groups_indirect = max_groups_indirect
+        else:
+            self.max_groups_indirect = 0
+        if max_groups_ff != None:
+            self.max_groups_ff = max_groups_ff
+        else:
+            self.max_groups_ff = 0
+        if actions_all != None:
+            self.actions_all = actions_all
+        else:
+            self.actions_all = 0
+        if actions_select != None:
+            self.actions_select = actions_select
+        else:
+            self.actions_select = 0
+        if actions_indirect != None:
+            self.actions_indirect = actions_indirect
+        else:
+            self.actions_indirect = 0
+        if actions_ff != None:
+            self.actions_ff = actions_ff
+        else:
+            self.actions_ff = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.types))
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.max_groups_all))
+        packed.append(struct.pack("!L", self.max_groups_select))
+        packed.append(struct.pack("!L", self.max_groups_indirect))
+        packed.append(struct.pack("!L", self.max_groups_ff))
+        packed.append(struct.pack("!L", self.actions_all))
+        packed.append(struct.pack("!L", self.actions_select))
+        packed.append(struct.pack("!L", self.actions_indirect))
+        packed.append(struct.pack("!L", self.actions_ff))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_features_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 8)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.types = reader.read("!L")[0]
+        obj.capabilities = reader.read("!L")[0]
+        obj.max_groups_all = reader.read("!L")[0]
+        obj.max_groups_select = reader.read("!L")[0]
+        obj.max_groups_indirect = reader.read("!L")[0]
+        obj.max_groups_ff = reader.read("!L")[0]
+        obj.actions_all = reader.read("!L")[0]
+        obj.actions_select = reader.read("!L")[0]
+        obj.actions_indirect = reader.read("!L")[0]
+        obj.actions_ff = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.types != other.types: return False
+        if self.capabilities != other.capabilities: return False
+        if self.max_groups_all != other.max_groups_all: return False
+        if self.max_groups_select != other.max_groups_select: return False
+        if self.max_groups_indirect != other.max_groups_indirect: return False
+        if self.max_groups_ff != other.max_groups_ff: return False
+        if self.actions_all != other.actions_all: return False
+        if self.actions_select != other.actions_select: return False
+        if self.actions_indirect != other.actions_indirect: return False
+        if self.actions_ff != other.actions_ff: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_features_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("types = ");
+                q.text("%#x" % self.types)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("max_groups_all = ");
+                q.text("%#x" % self.max_groups_all)
+                q.text(","); q.breakable()
+                q.text("max_groups_select = ");
+                q.text("%#x" % self.max_groups_select)
+                q.text(","); q.breakable()
+                q.text("max_groups_indirect = ");
+                q.text("%#x" % self.max_groups_indirect)
+                q.text(","); q.breakable()
+                q.text("max_groups_ff = ");
+                q.text("%#x" % self.max_groups_ff)
+                q.text(","); q.breakable()
+                q.text("actions_all = ");
+                q.text("%#x" % self.actions_all)
+                q.text(","); q.breakable()
+                q.text("actions_select = ");
+                q.text("%#x" % self.actions_select)
+                q.text(","); q.breakable()
+                q.text("actions_indirect = ");
+                q.text("%#x" % self.actions_indirect)
+                q.text(","); q.breakable()
+                q.text("actions_ff = ");
+                q.text("%#x" % self.actions_ff)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[8] = group_features_stats_reply
+
+class group_features_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 8
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_features_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 8)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_features_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[8] = group_features_stats_request
+
+class group_mod_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 6
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 6)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[6] = group_mod_failed_error_msg
+
+class group_modify(group_mod):
+    version = 5
+    type = 15
+    command = 1
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 1)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[1] = group_modify
+
+class group_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[6] = group_stats_reply
+
+class group_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, group_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.group_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[6] = group_stats_request
+
+class hello(message):
+    version = 5
+    type = 0
+
+    def __init__(self, xid=None, elements=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if elements != None:
+            self.elements = elements
+        else:
+            self.elements = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(loxi.generic_util.pack_list(self.elements))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.elements = loxi.generic_util.unpack_list(reader, ofp.common.hello_elem.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.elements != other.elements: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("elements = ");
+                q.pp(self.elements)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[0] = hello
+
+class hello_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 0
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 0)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[0] = hello_failed_error_msg
+
+class meter_config_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 10
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_config_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 10)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.meter_band.meter_band.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_config_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[10] = meter_config_stats_reply
+
+class meter_config_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 10
+
+    def __init__(self, xid=None, flags=None, meter_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_config_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 10)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.meter_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_config_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[10] = meter_config_stats_request
+
+class meter_features_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 11
+
+    def __init__(self, xid=None, flags=None, features=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if features != None:
+            self.features = features
+        else:
+            self.features = ofp.meter_features()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(self.features.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_features_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 11)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.features = ofp.meter_features.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.features != other.features: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_features_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("features = ");
+                q.pp(self.features)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[11] = meter_features_stats_reply
+
+class meter_features_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 11
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_features_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 11)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_features_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[11] = meter_features_stats_request
+
+class meter_mod(message):
+    version = 5
+    type = 29
+
+    def __init__(self, xid=None, command=None, flags=None, meter_id=None, bands=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if command != None:
+            self.command = command
+        else:
+            self.command = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        if bands != None:
+            self.bands = bands
+        else:
+            self.bands = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append(loxi.generic_util.pack_list(self.bands))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 29)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.command = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.meter_id = reader.read("!L")[0]
+        obj.bands = loxi.generic_util.unpack_list(reader, ofp.meter_band.meter_band.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.command != other.command: return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        if self.bands != other.bands: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("command = ");
+                q.text("%#x" % self.command)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+                q.text(","); q.breakable()
+                q.text("bands = ");
+                q.pp(self.bands)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[29] = meter_mod
+
+class meter_mod_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 12
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 12)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[12] = meter_mod_failed_error_msg
+
+class meter_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 9
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 9)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.meter_stats.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[9] = meter_stats_reply
+
+class meter_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 9
+
+    def __init__(self, xid=None, flags=None, meter_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 9)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.meter_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[9] = meter_stats_request
+
+class nicira_header(experimenter):
+    subtypes = {}
+
+    version = 5
+    type = 4
+    experimenter = 8992
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = nicira_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira_header
+
+class packet_in(message):
+    version = 5
+    type = 10
+
+    def __init__(self, xid=None, buffer_id=None, total_len=None, reason=None, table_id=None, cookie=None, match=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if total_len != None:
+            self.total_len = total_len
+        else:
+            self.total_len = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(struct.pack("!H", self.total_len))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(self.match.pack())
+        packed.append('\x00' * 2)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_in()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.total_len = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        reader.skip(2)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.total_len != other.total_len: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.cookie != other.cookie: return False
+        if self.match != other.match: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("total_len = ");
+                q.text("%#x" % self.total_len)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[10] = packet_in
+
+class packet_out(message):
+    version = 5
+    type = 13
+
+    def __init__(self, xid=None, buffer_id=None, in_port=None, actions=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(struct.pack("!H", 0)) # placeholder for actions_len at index 6
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        packed[6] = struct.pack("!H", len(packed[-1]))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_out()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.in_port = util.unpack_port_no(reader)
+        _actions_len = reader.read("!H")[0]
+        reader.skip(6)
+        obj.actions = loxi.generic_util.unpack_list(reader.slice(_actions_len), ofp.action.action.unpack)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.in_port != other.in_port: return False
+        if self.actions != other.actions: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[13] = packet_out
+
+class port_desc_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 13
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 13)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.port_desc.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[13] = port_desc_stats_reply
+
+class port_desc_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 13
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 13)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[13] = port_desc_stats_request
+
+class port_mod(message):
+    version = 5
+    type = 16
+
+    def __init__(self, xid=None, port_no=None, hw_addr=None, config=None, mask=None, properties=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.mask))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.config = reader.read("!L")[0]
+        obj.mask = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.port_mod_prop.port_mod_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.config != other.config: return False
+        if self.mask != other.mask: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[16] = port_mod
+
+class port_mod_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 7
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 7)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[7] = port_mod_failed_error_msg
+
+class port_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.port_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[4] = port_stats_reply
+
+class port_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[4] = port_stats_request
+
+class port_status(message):
+    version = 5
+    type = 12
+
+    def __init__(self, xid=None, reason=None, desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if desc != None:
+            self.desc = desc
+        else:
+            self.desc = ofp.port_desc()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 7)
+        packed.append(self.desc.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(7)
+        obj.desc = ofp.port_desc.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.reason != other.reason: return False
+        if self.desc != other.desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("desc = ");
+                q.pp(self.desc)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[12] = port_status
+
+class queue_desc_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 15
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 15)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.queue_desc.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[15] = queue_desc_stats_reply
+
+class queue_desc_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 15
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 15)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[15] = queue_desc_stats_request
+
+class queue_op_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 9
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_op_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 9)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_op_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[9] = queue_op_failed_error_msg
+
+class queue_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.queue_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[5] = queue_stats_reply
+
+class queue_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, port_no=None, queue_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[5] = queue_stats_request
+
+class requestforward(message):
+    version = 5
+    type = 32
+
+    def __init__(self, xid=None, role=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = requestforward()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 32)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("requestforward {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[32] = requestforward
+
+class role_reply(message):
+    version = 5
+    type = 25
+
+    def __init__(self, xid=None, role=None, generation_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 25)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        reader.skip(4)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[25] = role_reply
+
+class role_request(message):
+    version = 5
+    type = 24
+
+    def __init__(self, xid=None, role=None, generation_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 24)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        reader.skip(4)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[24] = role_request
+
+class role_request_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 11
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_request_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 11)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_request_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[11] = role_request_failed_error_msg
+
+class role_status(message):
+    version = 5
+    type = 30
+
+    def __init__(self, xid=None, role=None, reason=None, generation_id=None, properties=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!Q", self.generation_id))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 30)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(3)
+        obj.generation_id = reader.read("!Q")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.role_prop.role_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.reason != other.reason: return False
+        if self.generation_id != other.generation_id: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[30] = role_status
+
+class set_config(message):
+    version = 5
+    type = 9
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_config()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_config {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[9] = set_config
+
+class switch_config_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 10
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = switch_config_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 10)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("switch_config_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[10] = switch_config_failed_error_msg
+
+class table_desc_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 14
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 14)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_desc.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[14] = table_desc_stats_reply
+
+class table_desc_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 14
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 14)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[14] = table_desc_stats_request
+
+class table_features_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 13
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 13)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[13] = table_features_failed_error_msg
+
+class table_features_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 12
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 12)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_features.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[12] = table_features_stats_reply
+
+class table_features_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 12
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 12)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_features.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[12] = table_features_stats_request
+
+class table_mod(message):
+    version = 5
+    type = 17
+
+    def __init__(self, xid=None, table_id=None, config=None, properties=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.config))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.config = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.table_mod_prop.table_mod_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.config != other.config: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[17] = table_mod
+
+class table_mod_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 8
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 8)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[8] = table_mod_failed_error_msg
+
+class table_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[3] = table_stats_reply
+
+class table_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[3] = table_stats_request
+
+class table_status(message):
+    version = 5
+    type = 31
+
+    def __init__(self, xid=None, role=None, reason=None, table=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table != None:
+            self.table = table
+        else:
+            self.table = ofp.table_desc()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 7)
+        packed.append(self.table.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 31)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(7)
+        obj.table = ofp.table_desc.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.reason != other.reason: return False
+        if self.table != other.table: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table = ");
+                q.pp(self.table)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[31] = table_status
+
+
+def parse_header(buf):
+    if len(buf) < 8:
+        raise loxi.ProtocolError("too short to be an OpenFlow message")
+    return struct.unpack_from("!BBHL", buf)
+
+def parse_message(buf):
+    msg_ver, msg_type, msg_len, msg_xid = parse_header(buf)
+    if msg_ver != ofp.OFP_VERSION and msg_type != ofp.OFPT_HELLO:
+        raise loxi.ProtocolError("wrong OpenFlow version (expected %d, got %d)" % (ofp.OFP_VERSION, msg_ver))
+    if len(buf) != msg_len:
+        raise loxi.ProtocolError("incorrect message size")
+    return message.unpack(loxi.generic_util.OFReader(buf))
diff --git a/Fabric/Utilities/src/python/loxi/of14/meter_band.py b/Fabric/Utilities/src/python/loxi/of14/meter_band.py
new file mode 100644
index 0000000..c676cf0
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/meter_band.py
@@ -0,0 +1,275 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class meter_band(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = meter_band.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = meter_band()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_band {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class drop(meter_band):
+    type = 1
+
+    def __init__(self, rate=None, burst_size=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        if burst_size != None:
+            self.burst_size = burst_size
+        else:
+            self.burst_size = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.rate))
+        packed.append(struct.pack("!L", self.burst_size))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = drop()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.rate = reader.read("!L")[0]
+        obj.burst_size = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        if self.burst_size != other.burst_size: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("drop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+                q.text(","); q.breakable()
+                q.text("burst_size = ");
+                q.text("%#x" % self.burst_size)
+            q.breakable()
+        q.text('}')
+
+meter_band.subtypes[1] = drop
+
+class dscp_remark(meter_band):
+    type = 2
+
+    def __init__(self, rate=None, burst_size=None, prec_level=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        if burst_size != None:
+            self.burst_size = burst_size
+        else:
+            self.burst_size = 0
+        if prec_level != None:
+            self.prec_level = prec_level
+        else:
+            self.prec_level = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.rate))
+        packed.append(struct.pack("!L", self.burst_size))
+        packed.append(struct.pack("!B", self.prec_level))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dscp_remark()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.rate = reader.read("!L")[0]
+        obj.burst_size = reader.read("!L")[0]
+        obj.prec_level = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        if self.burst_size != other.burst_size: return False
+        if self.prec_level != other.prec_level: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dscp_remark {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+                q.text(","); q.breakable()
+                q.text("burst_size = ");
+                q.text("%#x" % self.burst_size)
+                q.text(","); q.breakable()
+                q.text("prec_level = ");
+                q.text("%#x" % self.prec_level)
+            q.breakable()
+        q.text('}')
+
+meter_band.subtypes[2] = dscp_remark
+
+class experimenter(meter_band):
+    type = 65535
+
+    def __init__(self, rate=None, burst_size=None, experimenter=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        if burst_size != None:
+            self.burst_size = burst_size
+        else:
+            self.burst_size = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.rate))
+        packed.append(struct.pack("!L", self.burst_size))
+        packed.append(struct.pack("!L", self.experimenter))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.rate = reader.read("!L")[0]
+        obj.burst_size = reader.read("!L")[0]
+        obj.experimenter = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        if self.burst_size != other.burst_size: return False
+        if self.experimenter != other.experimenter: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+                q.text(","); q.breakable()
+                q.text("burst_size = ");
+                q.text("%#x" % self.burst_size)
+                q.text(","); q.breakable()
+                q.text("experimenter = ");
+                q.text("%#x" % self.experimenter)
+            q.breakable()
+        q.text('}')
+
+meter_band.subtypes[65535] = experimenter
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/oxm.py b/Fabric/Utilities/src/python/loxi/of14/oxm.py
new file mode 100644
index 0000000..88e1fce
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/oxm.py
@@ -0,0 +1,5962 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class oxm(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type_len=None):
+        if type_len != None:
+            self.type_len = type_len
+        else:
+            self.type_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 0)
+        subclass = oxm.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = oxm()
+        obj.type_len = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type_len != other.type_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("oxm {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class arp_op(oxm):
+    type_len = 2147494402
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_op()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494402)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_op {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494402] = arp_op
+
+class arp_op_masked(oxm):
+    type_len = 2147494660
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_op_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494660)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_op_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494660] = arp_op_masked
+
+class arp_sha(oxm):
+    type_len = 2147495942
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_sha()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495942)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_sha {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495942] = arp_sha
+
+class arp_sha_masked(oxm):
+    type_len = 2147496204
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_sha_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496204)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_sha_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496204] = arp_sha_masked
+
+class arp_spa(oxm):
+    type_len = 2147494916
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_spa()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494916)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_spa {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494916] = arp_spa
+
+class arp_spa_masked(oxm):
+    type_len = 2147495176
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_spa_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495176)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_spa_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495176] = arp_spa_masked
+
+class arp_tha(oxm):
+    type_len = 2147496454
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tha()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496454)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tha {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496454] = arp_tha
+
+class arp_tha_masked(oxm):
+    type_len = 2147496716
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tha_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496716)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tha_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496716] = arp_tha_masked
+
+class arp_tpa(oxm):
+    type_len = 2147495428
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tpa()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495428)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tpa {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495428] = arp_tpa
+
+class arp_tpa_masked(oxm):
+    type_len = 2147495688
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tpa_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495688)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tpa_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495688] = arp_tpa_masked
+
+class bsn_egr_port_group_id(oxm):
+    type_len = 200196
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_egr_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200196)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_egr_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200196] = bsn_egr_port_group_id
+
+class bsn_egr_port_group_id_masked(oxm):
+    type_len = 200456
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_egr_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200456)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_egr_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200456] = bsn_egr_port_group_id_masked
+
+class bsn_in_ports_128(oxm):
+    type_len = 196624
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_128(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_128()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 196624)
+        obj.value = util.unpack_bitmap_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_128 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[196624] = bsn_in_ports_128
+
+class bsn_in_ports_128_masked(oxm):
+    type_len = 196896
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_128(self.value))
+        packed.append(util.pack_bitmap_128(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_128_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 196896)
+        obj.value = util.unpack_bitmap_128(reader)
+        obj.value_mask = util.unpack_bitmap_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_128_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[196896] = bsn_in_ports_128_masked
+
+class bsn_in_ports_512(oxm):
+    type_len = 206400
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_512(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_512()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206400)
+        obj.value = util.unpack_bitmap_512(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_512 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206400] = bsn_in_ports_512
+
+class bsn_in_ports_512_masked(oxm):
+    type_len = 206720
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_512(self.value))
+        packed.append(util.pack_bitmap_512(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_512_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206720)
+        obj.value = util.unpack_bitmap_512(reader)
+        obj.value_mask = util.unpack_bitmap_512(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_512_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206720] = bsn_in_ports_512_masked
+
+class bsn_ingress_port_group_id(oxm):
+    type_len = 206852
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_ingress_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206852)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_ingress_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206852] = bsn_ingress_port_group_id
+
+class bsn_ingress_port_group_id_masked(oxm):
+    type_len = 207112
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_ingress_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207112)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_ingress_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207112] = bsn_ingress_port_group_id_masked
+
+class bsn_inner_eth_dst(oxm):
+    type_len = 207878
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207878)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207878] = bsn_inner_eth_dst
+
+class bsn_inner_eth_dst_masked(oxm):
+    type_len = 208140
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208140)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208140] = bsn_inner_eth_dst_masked
+
+class bsn_inner_eth_src(oxm):
+    type_len = 208390
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208390)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208390] = bsn_inner_eth_src
+
+class bsn_inner_eth_src_masked(oxm):
+    type_len = 208652
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208652)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208652] = bsn_inner_eth_src_masked
+
+class bsn_inner_vlan_vid(oxm):
+    type_len = 208898
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_vlan_vid()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208898)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208898] = bsn_inner_vlan_vid
+
+class bsn_inner_vlan_vid_masked(oxm):
+    type_len = 209156
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_vlan_vid_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 209156)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_vlan_vid_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[209156] = bsn_inner_vlan_vid_masked
+
+class bsn_l3_interface_class_id(oxm):
+    type_len = 198660
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_interface_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198660)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_interface_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198660] = bsn_l3_interface_class_id
+
+class bsn_l3_interface_class_id_masked(oxm):
+    type_len = 198920
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_interface_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198920)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_interface_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198920] = bsn_l3_interface_class_id_masked
+
+class bsn_l3_src_class_id(oxm):
+    type_len = 199172
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_src_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199172)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_src_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199172] = bsn_l3_src_class_id
+
+class bsn_l3_src_class_id_masked(oxm):
+    type_len = 199432
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_src_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199432)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_src_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199432] = bsn_l3_src_class_id_masked
+
+class bsn_lag_id(oxm):
+    type_len = 197124
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lag_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197124)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lag_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197124] = bsn_lag_id
+
+class bsn_lag_id_masked(oxm):
+    type_len = 197384
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lag_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197384)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lag_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197384] = bsn_lag_id_masked
+
+class bsn_tcp_flags(oxm):
+    type_len = 204802
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_tcp_flags()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204802)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tcp_flags {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204802] = bsn_tcp_flags
+
+class bsn_tcp_flags_masked(oxm):
+    type_len = 205060
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_tcp_flags_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205060)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tcp_flags_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205060] = bsn_tcp_flags_masked
+
+class bsn_udf0(oxm):
+    type_len = 200708
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf0()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200708)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf0 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200708] = bsn_udf0
+
+class bsn_udf0_masked(oxm):
+    type_len = 200968
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf0_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200968)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf0_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200968] = bsn_udf0_masked
+
+class bsn_udf1(oxm):
+    type_len = 201220
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf1()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201220)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf1 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201220] = bsn_udf1
+
+class bsn_udf1_masked(oxm):
+    type_len = 201480
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf1_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201480)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf1_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201480] = bsn_udf1_masked
+
+class bsn_udf2(oxm):
+    type_len = 201732
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf2()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201732)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf2 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201732] = bsn_udf2
+
+class bsn_udf2_masked(oxm):
+    type_len = 201992
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf2_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201992)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf2_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201992] = bsn_udf2_masked
+
+class bsn_udf3(oxm):
+    type_len = 202244
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf3()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202244)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202244] = bsn_udf3
+
+class bsn_udf3_masked(oxm):
+    type_len = 202504
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf3_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202504)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf3_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202504] = bsn_udf3_masked
+
+class bsn_udf4(oxm):
+    type_len = 202756
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf4()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202756)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf4 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202756] = bsn_udf4
+
+class bsn_udf4_masked(oxm):
+    type_len = 203016
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf4_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203016)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf4_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203016] = bsn_udf4_masked
+
+class bsn_udf5(oxm):
+    type_len = 203268
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf5()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203268)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf5 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203268] = bsn_udf5
+
+class bsn_udf5_masked(oxm):
+    type_len = 203528
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf5_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203528)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf5_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203528] = bsn_udf5_masked
+
+class bsn_udf6(oxm):
+    type_len = 203780
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf6()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203780)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf6 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203780] = bsn_udf6
+
+class bsn_udf6_masked(oxm):
+    type_len = 204040
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf6_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204040)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf6_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204040] = bsn_udf6_masked
+
+class bsn_udf7(oxm):
+    type_len = 204292
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf7()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204292)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf7 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204292] = bsn_udf7
+
+class bsn_udf7_masked(oxm):
+    type_len = 204552
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf7_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204552)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf7_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204552] = bsn_udf7_masked
+
+class bsn_vlan_xlate_port_group_id(oxm):
+    type_len = 205316
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_xlate_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205316)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_xlate_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205316] = bsn_vlan_xlate_port_group_id
+
+class bsn_vlan_xlate_port_group_id_masked(oxm):
+    type_len = 205576
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_xlate_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205576)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_xlate_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205576] = bsn_vlan_xlate_port_group_id_masked
+
+class bsn_vrf(oxm):
+    type_len = 197636
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197636)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197636] = bsn_vrf
+
+class bsn_vrf_masked(oxm):
+    type_len = 197896
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197896)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197896] = bsn_vrf_masked
+
+class bsn_vxlan_network_id(oxm):
+    type_len = 207364
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vxlan_network_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207364)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vxlan_network_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207364] = bsn_vxlan_network_id
+
+class bsn_vxlan_network_id_masked(oxm):
+    type_len = 207624
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vxlan_network_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207624)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vxlan_network_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207624] = bsn_vxlan_network_id_masked
+
+class eth_dst(oxm):
+    type_len = 2147485190
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485190)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485190] = eth_dst
+
+class eth_dst_masked(oxm):
+    type_len = 2147485452
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485452)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485452] = eth_dst_masked
+
+class eth_src(oxm):
+    type_len = 2147485702
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485702)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485702] = eth_src
+
+class eth_src_masked(oxm):
+    type_len = 2147485964
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485964)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485964] = eth_src_masked
+
+class eth_type(oxm):
+    type_len = 2147486210
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486210)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486210] = eth_type
+
+class eth_type_masked(oxm):
+    type_len = 2147486468
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486468)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486468] = eth_type_masked
+
+class icmpv4_code(oxm):
+    type_len = 2147493889
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_code()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493889)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493889] = icmpv4_code
+
+class icmpv4_code_masked(oxm):
+    type_len = 2147494146
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_code_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494146)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_code_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494146] = icmpv4_code_masked
+
+class icmpv4_type(oxm):
+    type_len = 2147493377
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493377)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493377] = icmpv4_type
+
+class icmpv4_type_masked(oxm):
+    type_len = 2147493634
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493634)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493634] = icmpv4_type_masked
+
+class icmpv6_code(oxm):
+    type_len = 2147499009
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_code()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499009)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499009] = icmpv6_code
+
+class icmpv6_code_masked(oxm):
+    type_len = 2147499266
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_code_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499266)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_code_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499266] = icmpv6_code_masked
+
+class icmpv6_type(oxm):
+    type_len = 2147498497
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498497)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498497] = icmpv6_type
+
+class icmpv6_type_masked(oxm):
+    type_len = 2147498754
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498754)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498754] = icmpv6_type_masked
+
+class in_phy_port(oxm):
+    type_len = 2147484164
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_phy_port()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484164)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_phy_port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484164] = in_phy_port
+
+class in_phy_port_masked(oxm):
+    type_len = 2147484424
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        packed.append(util.pack_port_no(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_phy_port_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484424)
+        obj.value = util.unpack_port_no(reader)
+        obj.value_mask = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_phy_port_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_port(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484424] = in_phy_port_masked
+
+class in_port(oxm):
+    type_len = 2147483652
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_port()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147483652)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147483652] = in_port
+
+class in_port_masked(oxm):
+    type_len = 2147483912
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        packed.append(util.pack_port_no(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_port_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147483912)
+        obj.value = util.unpack_port_no(reader)
+        obj.value_mask = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_port_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_port(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147483912] = in_port_masked
+
+class ip_dscp(oxm):
+    type_len = 2147487745
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_dscp()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487745)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_dscp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487745] = ip_dscp
+
+class ip_dscp_masked(oxm):
+    type_len = 2147488002
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_dscp_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488002)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_dscp_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488002] = ip_dscp_masked
+
+class ip_ecn(oxm):
+    type_len = 2147488257
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_ecn()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488257)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_ecn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488257] = ip_ecn
+
+class ip_ecn_masked(oxm):
+    type_len = 2147488514
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_ecn_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488514)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_ecn_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488514] = ip_ecn_masked
+
+class ip_proto(oxm):
+    type_len = 2147488769
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488769)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488769] = ip_proto
+
+class ip_proto_masked(oxm):
+    type_len = 2147489026
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489026)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489026] = ip_proto_masked
+
+class ipv4_dst(oxm):
+    type_len = 2147489796
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489796)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489796] = ipv4_dst
+
+class ipv4_dst_masked(oxm):
+    type_len = 2147490056
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490056)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490056] = ipv4_dst_masked
+
+class ipv4_src(oxm):
+    type_len = 2147489284
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489284)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489284] = ipv4_src
+
+class ipv4_src_masked(oxm):
+    type_len = 2147489544
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489544)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489544] = ipv4_src_masked
+
+class ipv6_dst(oxm):
+    type_len = 2147497488
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497488)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497488] = ipv6_dst
+
+class ipv6_dst_masked(oxm):
+    type_len = 2147497760
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497760)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497760] = ipv6_dst_masked
+
+class ipv6_exthdr(oxm):
+    type_len = 2147503618
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_exthdr()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503618)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_exthdr {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503618] = ipv6_exthdr
+
+class ipv6_exthdr_masked(oxm):
+    type_len = 2147503876
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_exthdr_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503876)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_exthdr_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503876] = ipv6_exthdr_masked
+
+class ipv6_flabel(oxm):
+    type_len = 2147497988
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_flabel()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497988)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_flabel {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497988] = ipv6_flabel
+
+class ipv6_flabel_masked(oxm):
+    type_len = 2147498248
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_flabel_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498248)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_flabel_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498248] = ipv6_flabel_masked
+
+class ipv6_nd_sll(oxm):
+    type_len = 2147500038
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_sll()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500038)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_sll {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500038] = ipv6_nd_sll
+
+class ipv6_nd_sll_masked(oxm):
+    type_len = 2147500300
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_sll_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500300)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_sll_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500300] = ipv6_nd_sll_masked
+
+class ipv6_nd_target(oxm):
+    type_len = 2147499536
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_target()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499536)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_target {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499536] = ipv6_nd_target
+
+class ipv6_nd_target_masked(oxm):
+    type_len = 2147499808
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_target_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499808)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_target_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499808] = ipv6_nd_target_masked
+
+class ipv6_nd_tll(oxm):
+    type_len = 2147500550
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_tll()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500550)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_tll {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500550] = ipv6_nd_tll
+
+class ipv6_nd_tll_masked(oxm):
+    type_len = 2147500812
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_tll_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500812)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_tll_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500812] = ipv6_nd_tll_masked
+
+class ipv6_src(oxm):
+    type_len = 2147496976
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496976)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496976] = ipv6_src
+
+class ipv6_src_masked(oxm):
+    type_len = 2147497248
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497248)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497248] = ipv6_src_masked
+
+class metadata(oxm):
+    type_len = 2147484680
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = metadata()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484680)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484680] = metadata
+
+class metadata_masked(oxm):
+    type_len = 2147484944
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        packed.append(struct.pack("!Q", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = metadata_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484944)
+        obj.value = reader.read("!Q")[0]
+        obj.value_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("metadata_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484944] = metadata_masked
+
+class mpls_bos(oxm):
+    type_len = 2147502081
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_bos()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147502081)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_bos {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147502081] = mpls_bos
+
+class mpls_bos_masked(oxm):
+    type_len = 2147502338
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_bos_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147502338)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_bos_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147502338] = mpls_bos_masked
+
+class mpls_label(oxm):
+    type_len = 2147501060
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501060)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501060] = mpls_label
+
+class mpls_label_masked(oxm):
+    type_len = 2147501320
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501320)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501320] = mpls_label_masked
+
+class mpls_tc(oxm):
+    type_len = 2147501569
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_tc()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501569)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_tc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501569] = mpls_tc
+
+class mpls_tc_masked(oxm):
+    type_len = 2147501826
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_tc_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501826)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_tc_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501826] = mpls_tc_masked
+
+class pbb_uca(oxm):
+    type_len = 2147504641
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pbb_uca()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147504641)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pbb_uca {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147504641] = pbb_uca
+
+class pbb_uca_masked(oxm):
+    type_len = 2147504898
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pbb_uca_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147504898)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pbb_uca_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147504898] = pbb_uca_masked
+
+class sctp_dst(oxm):
+    type_len = 2147492866
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492866)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492866] = sctp_dst
+
+class sctp_dst_masked(oxm):
+    type_len = 2147493124
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493124)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493124] = sctp_dst_masked
+
+class sctp_src(oxm):
+    type_len = 2147492354
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492354)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492354] = sctp_src
+
+class sctp_src_masked(oxm):
+    type_len = 2147492612
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492612)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492612] = sctp_src_masked
+
+class tcp_dst(oxm):
+    type_len = 2147490818
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490818)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490818] = tcp_dst
+
+class tcp_dst_masked(oxm):
+    type_len = 2147491076
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491076)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491076] = tcp_dst_masked
+
+class tcp_src(oxm):
+    type_len = 2147490306
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490306)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490306] = tcp_src
+
+class tcp_src_masked(oxm):
+    type_len = 2147490564
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490564)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490564] = tcp_src_masked
+
+class tunnel_id(oxm):
+    type_len = 2147503112
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503112)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503112] = tunnel_id
+
+class tunnel_id_masked(oxm):
+    type_len = 2147503376
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        packed.append(struct.pack("!Q", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503376)
+        obj.value = reader.read("!Q")[0]
+        obj.value_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503376] = tunnel_id_masked
+
+class tunnel_ipv4_dst(oxm):
+    type_len = 81924
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81924)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81924] = tunnel_ipv4_dst
+
+class tunnel_ipv4_dst_masked(oxm):
+    type_len = 82184
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 82184)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[82184] = tunnel_ipv4_dst_masked
+
+class tunnel_ipv4_src(oxm):
+    type_len = 81412
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81412)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81412] = tunnel_ipv4_src
+
+class tunnel_ipv4_src_masked(oxm):
+    type_len = 81672
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81672)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81672] = tunnel_ipv4_src_masked
+
+class udp_dst(oxm):
+    type_len = 2147491842
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491842)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491842] = udp_dst
+
+class udp_dst_masked(oxm):
+    type_len = 2147492100
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492100)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492100] = udp_dst_masked
+
+class udp_src(oxm):
+    type_len = 2147491330
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491330)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491330] = udp_src
+
+class udp_src_masked(oxm):
+    type_len = 2147491588
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491588)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491588] = udp_src_masked
+
+class vlan_pcp(oxm):
+    type_len = 2147487233
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487233)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487233] = vlan_pcp
+
+class vlan_pcp_masked(oxm):
+    type_len = 2147487490
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487490)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487490] = vlan_pcp_masked
+
+class vlan_vid(oxm):
+    type_len = 2147486722
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486722)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486722] = vlan_vid
+
+class vlan_vid_masked(oxm):
+    type_len = 2147486980
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486980)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486980] = vlan_vid_masked
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/port_desc_prop.py b/Fabric/Utilities/src/python/loxi/of14/port_desc_prop.py
new file mode 100644
index 0000000..71f281d
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/port_desc_prop.py
@@ -0,0 +1,517 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class port_desc_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = port_desc_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = port_desc_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(port_desc_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+port_desc_prop.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, exp_type=None):
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.exp_type = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_generation_id(bsn):
+    type = 65535
+    experimenter = 6035143
+    exp_type = 1
+
+    def __init__(self, generation_id=None):
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generation_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _exp_type = reader.read("!L")[0]
+        assert(_exp_type == 1)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generation_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_generation_id
+
+class bsn_uplink(bsn):
+    type = 65535
+    experimenter = 6035143
+    exp_type = 0
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_uplink()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _exp_type = reader.read("!L")[0]
+        assert(_exp_type == 0)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_uplink {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[0] = bsn_uplink
+
+class ethernet(port_desc_prop):
+    type = 0
+
+    def __init__(self, curr=None, advertised=None, supported=None, peer=None, curr_speed=None, max_speed=None):
+        if curr != None:
+            self.curr = curr
+        else:
+            self.curr = 0
+        if advertised != None:
+            self.advertised = advertised
+        else:
+            self.advertised = 0
+        if supported != None:
+            self.supported = supported
+        else:
+            self.supported = 0
+        if peer != None:
+            self.peer = peer
+        else:
+            self.peer = 0
+        if curr_speed != None:
+            self.curr_speed = curr_speed
+        else:
+            self.curr_speed = 0
+        if max_speed != None:
+            self.max_speed = max_speed
+        else:
+            self.max_speed = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.curr))
+        packed.append(struct.pack("!L", self.advertised))
+        packed.append(struct.pack("!L", self.supported))
+        packed.append(struct.pack("!L", self.peer))
+        packed.append(struct.pack("!L", self.curr_speed))
+        packed.append(struct.pack("!L", self.max_speed))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ethernet()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        reader.skip(4)
+        obj.curr = reader.read("!L")[0]
+        obj.advertised = reader.read("!L")[0]
+        obj.supported = reader.read("!L")[0]
+        obj.peer = reader.read("!L")[0]
+        obj.curr_speed = reader.read("!L")[0]
+        obj.max_speed = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.curr != other.curr: return False
+        if self.advertised != other.advertised: return False
+        if self.supported != other.supported: return False
+        if self.peer != other.peer: return False
+        if self.curr_speed != other.curr_speed: return False
+        if self.max_speed != other.max_speed: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ethernet {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("curr = ");
+                q.text("%#x" % self.curr)
+                q.text(","); q.breakable()
+                q.text("advertised = ");
+                q.text("%#x" % self.advertised)
+                q.text(","); q.breakable()
+                q.text("supported = ");
+                q.text("%#x" % self.supported)
+                q.text(","); q.breakable()
+                q.text("peer = ");
+                q.text("%#x" % self.peer)
+                q.text(","); q.breakable()
+                q.text("curr_speed = ");
+                q.text("%#x" % self.curr_speed)
+                q.text(","); q.breakable()
+                q.text("max_speed = ");
+                q.text("%#x" % self.max_speed)
+            q.breakable()
+        q.text('}')
+
+port_desc_prop.subtypes[0] = ethernet
+
+class optical(port_desc_prop):
+    type = 1
+
+    def __init__(self, supported=None, tx_min_freq_lmda=None, tx_max_freq_lmda=None, tx_grid_freq_lmda=None, rx_min_freq_lmda=None, rx_max_freq_lmda=None, rx_grid_freq_lmda=None, tx_pwr_min=None, tx_pwr_max=None):
+        if supported != None:
+            self.supported = supported
+        else:
+            self.supported = 0
+        if tx_min_freq_lmda != None:
+            self.tx_min_freq_lmda = tx_min_freq_lmda
+        else:
+            self.tx_min_freq_lmda = 0
+        if tx_max_freq_lmda != None:
+            self.tx_max_freq_lmda = tx_max_freq_lmda
+        else:
+            self.tx_max_freq_lmda = 0
+        if tx_grid_freq_lmda != None:
+            self.tx_grid_freq_lmda = tx_grid_freq_lmda
+        else:
+            self.tx_grid_freq_lmda = 0
+        if rx_min_freq_lmda != None:
+            self.rx_min_freq_lmda = rx_min_freq_lmda
+        else:
+            self.rx_min_freq_lmda = 0
+        if rx_max_freq_lmda != None:
+            self.rx_max_freq_lmda = rx_max_freq_lmda
+        else:
+            self.rx_max_freq_lmda = 0
+        if rx_grid_freq_lmda != None:
+            self.rx_grid_freq_lmda = rx_grid_freq_lmda
+        else:
+            self.rx_grid_freq_lmda = 0
+        if tx_pwr_min != None:
+            self.tx_pwr_min = tx_pwr_min
+        else:
+            self.tx_pwr_min = 0
+        if tx_pwr_max != None:
+            self.tx_pwr_max = tx_pwr_max
+        else:
+            self.tx_pwr_max = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.supported))
+        packed.append(struct.pack("!L", self.tx_min_freq_lmda))
+        packed.append(struct.pack("!L", self.tx_max_freq_lmda))
+        packed.append(struct.pack("!L", self.tx_grid_freq_lmda))
+        packed.append(struct.pack("!L", self.rx_min_freq_lmda))
+        packed.append(struct.pack("!L", self.rx_max_freq_lmda))
+        packed.append(struct.pack("!L", self.rx_grid_freq_lmda))
+        packed.append(struct.pack("!L", self.tx_pwr_min))
+        packed.append(struct.pack("!L", self.tx_pwr_max))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = optical()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        reader.skip(4)
+        obj.supported = reader.read("!L")[0]
+        obj.tx_min_freq_lmda = reader.read("!L")[0]
+        obj.tx_max_freq_lmda = reader.read("!L")[0]
+        obj.tx_grid_freq_lmda = reader.read("!L")[0]
+        obj.rx_min_freq_lmda = reader.read("!L")[0]
+        obj.rx_max_freq_lmda = reader.read("!L")[0]
+        obj.rx_grid_freq_lmda = reader.read("!L")[0]
+        obj.tx_pwr_min = reader.read("!L")[0]
+        obj.tx_pwr_max = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.supported != other.supported: return False
+        if self.tx_min_freq_lmda != other.tx_min_freq_lmda: return False
+        if self.tx_max_freq_lmda != other.tx_max_freq_lmda: return False
+        if self.tx_grid_freq_lmda != other.tx_grid_freq_lmda: return False
+        if self.rx_min_freq_lmda != other.rx_min_freq_lmda: return False
+        if self.rx_max_freq_lmda != other.rx_max_freq_lmda: return False
+        if self.rx_grid_freq_lmda != other.rx_grid_freq_lmda: return False
+        if self.tx_pwr_min != other.tx_pwr_min: return False
+        if self.tx_pwr_max != other.tx_pwr_max: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("optical {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("supported = ");
+                q.text("%#x" % self.supported)
+                q.text(","); q.breakable()
+                q.text("tx_min_freq_lmda = ");
+                q.text("%#x" % self.tx_min_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("tx_max_freq_lmda = ");
+                q.text("%#x" % self.tx_max_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("tx_grid_freq_lmda = ");
+                q.text("%#x" % self.tx_grid_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("rx_min_freq_lmda = ");
+                q.text("%#x" % self.rx_min_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("rx_max_freq_lmda = ");
+                q.text("%#x" % self.rx_max_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("rx_grid_freq_lmda = ");
+                q.text("%#x" % self.rx_grid_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("tx_pwr_min = ");
+                q.text("%#x" % self.tx_pwr_min)
+                q.text(","); q.breakable()
+                q.text("tx_pwr_max = ");
+                q.text("%#x" % self.tx_pwr_max)
+            q.breakable()
+        q.text('}')
+
+port_desc_prop.subtypes[1] = optical
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/port_mod_prop.py b/Fabric/Utilities/src/python/loxi/of14/port_mod_prop.py
new file mode 100644
index 0000000..ce9e448
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/port_mod_prop.py
@@ -0,0 +1,275 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class port_mod_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = port_mod_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = port_mod_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class ethernet(port_mod_prop):
+    type = 0
+
+    def __init__(self, advertise=None):
+        if advertise != None:
+            self.advertise = advertise
+        else:
+            self.advertise = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.advertise))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ethernet()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.advertise = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.advertise != other.advertise: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ethernet {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("advertise = ");
+                q.text("%#x" % self.advertise)
+            q.breakable()
+        q.text('}')
+
+port_mod_prop.subtypes[0] = ethernet
+
+class experimenter(port_mod_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, exp_type=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.exp_type = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("exp_type = ");
+                q.text("%#x" % self.exp_type)
+            q.breakable()
+        q.text('}')
+
+port_mod_prop.subtypes[65535] = experimenter
+
+class optical(port_mod_prop):
+    type = 1
+
+    def __init__(self, configure=None, freq_ldma=None, fl_offset=None, grid_span=None, tx_pwr=None):
+        if configure != None:
+            self.configure = configure
+        else:
+            self.configure = 0
+        if freq_ldma != None:
+            self.freq_ldma = freq_ldma
+        else:
+            self.freq_ldma = 0
+        if fl_offset != None:
+            self.fl_offset = fl_offset
+        else:
+            self.fl_offset = 0
+        if grid_span != None:
+            self.grid_span = grid_span
+        else:
+            self.grid_span = 0
+        if tx_pwr != None:
+            self.tx_pwr = tx_pwr
+        else:
+            self.tx_pwr = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.configure))
+        packed.append(struct.pack("!L", self.freq_ldma))
+        packed.append(struct.pack("!L", self.fl_offset))
+        packed.append(struct.pack("!L", self.grid_span))
+        packed.append(struct.pack("!L", self.tx_pwr))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = optical()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.configure = reader.read("!L")[0]
+        obj.freq_ldma = reader.read("!L")[0]
+        obj.fl_offset = reader.read("!L")[0]
+        obj.grid_span = reader.read("!L")[0]
+        obj.tx_pwr = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.configure != other.configure: return False
+        if self.freq_ldma != other.freq_ldma: return False
+        if self.fl_offset != other.fl_offset: return False
+        if self.grid_span != other.grid_span: return False
+        if self.tx_pwr != other.tx_pwr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("optical {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("configure = ");
+                q.text("%#x" % self.configure)
+                q.text(","); q.breakable()
+                q.text("freq_ldma = ");
+                q.text("%#x" % self.freq_ldma)
+                q.text(","); q.breakable()
+                q.text("fl_offset = ");
+                q.text("%#x" % self.fl_offset)
+                q.text(","); q.breakable()
+                q.text("grid_span = ");
+                q.text("%#x" % self.grid_span)
+                q.text(","); q.breakable()
+                q.text("tx_pwr = ");
+                q.text("%#x" % self.tx_pwr)
+            q.breakable()
+        q.text('}')
+
+port_mod_prop.subtypes[1] = optical
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/port_stats_prop.py b/Fabric/Utilities/src/python/loxi/of14/port_stats_prop.py
new file mode 100644
index 0000000..752ac6d
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/port_stats_prop.py
@@ -0,0 +1,379 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class port_stats_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = port_stats_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = port_stats_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class ethernet(port_stats_prop):
+    type = 0
+
+    def __init__(self, rx_frame_err=None, rx_over_err=None, rx_crc_err=None, collisions=None):
+        if rx_frame_err != None:
+            self.rx_frame_err = rx_frame_err
+        else:
+            self.rx_frame_err = 0
+        if rx_over_err != None:
+            self.rx_over_err = rx_over_err
+        else:
+            self.rx_over_err = 0
+        if rx_crc_err != None:
+            self.rx_crc_err = rx_crc_err
+        else:
+            self.rx_crc_err = 0
+        if collisions != None:
+            self.collisions = collisions
+        else:
+            self.collisions = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.rx_frame_err))
+        packed.append(struct.pack("!Q", self.rx_over_err))
+        packed.append(struct.pack("!Q", self.rx_crc_err))
+        packed.append(struct.pack("!Q", self.collisions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ethernet()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        reader.skip(4)
+        obj.rx_frame_err = reader.read("!Q")[0]
+        obj.rx_over_err = reader.read("!Q")[0]
+        obj.rx_crc_err = reader.read("!Q")[0]
+        obj.collisions = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rx_frame_err != other.rx_frame_err: return False
+        if self.rx_over_err != other.rx_over_err: return False
+        if self.rx_crc_err != other.rx_crc_err: return False
+        if self.collisions != other.collisions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ethernet {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rx_frame_err = ");
+                q.text("%#x" % self.rx_frame_err)
+                q.text(","); q.breakable()
+                q.text("rx_over_err = ");
+                q.text("%#x" % self.rx_over_err)
+                q.text(","); q.breakable()
+                q.text("rx_crc_err = ");
+                q.text("%#x" % self.rx_crc_err)
+                q.text(","); q.breakable()
+                q.text("collisions = ");
+                q.text("%#x" % self.collisions)
+            q.breakable()
+        q.text('}')
+
+port_stats_prop.subtypes[0] = ethernet
+
+class experimenter(port_stats_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, exp_type=None, experimenter_data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        if experimenter_data != None:
+            self.experimenter_data = experimenter_data
+        else:
+            self.experimenter_data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        packed.append(self.experimenter_data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.exp_type = reader.read("!L")[0]
+        obj.experimenter_data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.exp_type != other.exp_type: return False
+        if self.experimenter_data != other.experimenter_data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("exp_type = ");
+                q.text("%#x" % self.exp_type)
+                q.text(","); q.breakable()
+                q.text("experimenter_data = ");
+                q.pp(self.experimenter_data)
+            q.breakable()
+        q.text('}')
+
+port_stats_prop.subtypes[65535] = experimenter
+
+class optical(port_stats_prop):
+    type = 1
+
+    def __init__(self, flags=None, tx_freq_lmda=None, tx_offset=None, tx_grid_span=None, rx_freq_lmda=None, rx_offset=None, rx_grid_span=None, tx_pwr=None, rx_pwr=None, bias_current=None, temperature=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if tx_freq_lmda != None:
+            self.tx_freq_lmda = tx_freq_lmda
+        else:
+            self.tx_freq_lmda = 0
+        if tx_offset != None:
+            self.tx_offset = tx_offset
+        else:
+            self.tx_offset = 0
+        if tx_grid_span != None:
+            self.tx_grid_span = tx_grid_span
+        else:
+            self.tx_grid_span = 0
+        if rx_freq_lmda != None:
+            self.rx_freq_lmda = rx_freq_lmda
+        else:
+            self.rx_freq_lmda = 0
+        if rx_offset != None:
+            self.rx_offset = rx_offset
+        else:
+            self.rx_offset = 0
+        if rx_grid_span != None:
+            self.rx_grid_span = rx_grid_span
+        else:
+            self.rx_grid_span = 0
+        if tx_pwr != None:
+            self.tx_pwr = tx_pwr
+        else:
+            self.tx_pwr = 0
+        if rx_pwr != None:
+            self.rx_pwr = rx_pwr
+        else:
+            self.rx_pwr = 0
+        if bias_current != None:
+            self.bias_current = bias_current
+        else:
+            self.bias_current = 0
+        if temperature != None:
+            self.temperature = temperature
+        else:
+            self.temperature = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.flags))
+        packed.append(struct.pack("!L", self.tx_freq_lmda))
+        packed.append(struct.pack("!L", self.tx_offset))
+        packed.append(struct.pack("!L", self.tx_grid_span))
+        packed.append(struct.pack("!L", self.rx_freq_lmda))
+        packed.append(struct.pack("!L", self.rx_offset))
+        packed.append(struct.pack("!L", self.rx_grid_span))
+        packed.append(struct.pack("!H", self.tx_pwr))
+        packed.append(struct.pack("!H", self.rx_pwr))
+        packed.append(struct.pack("!H", self.bias_current))
+        packed.append(struct.pack("!H", self.temperature))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = optical()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        reader.skip(4)
+        obj.flags = reader.read("!L")[0]
+        obj.tx_freq_lmda = reader.read("!L")[0]
+        obj.tx_offset = reader.read("!L")[0]
+        obj.tx_grid_span = reader.read("!L")[0]
+        obj.rx_freq_lmda = reader.read("!L")[0]
+        obj.rx_offset = reader.read("!L")[0]
+        obj.rx_grid_span = reader.read("!L")[0]
+        obj.tx_pwr = reader.read("!H")[0]
+        obj.rx_pwr = reader.read("!H")[0]
+        obj.bias_current = reader.read("!H")[0]
+        obj.temperature = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.tx_freq_lmda != other.tx_freq_lmda: return False
+        if self.tx_offset != other.tx_offset: return False
+        if self.tx_grid_span != other.tx_grid_span: return False
+        if self.rx_freq_lmda != other.rx_freq_lmda: return False
+        if self.rx_offset != other.rx_offset: return False
+        if self.rx_grid_span != other.rx_grid_span: return False
+        if self.tx_pwr != other.tx_pwr: return False
+        if self.rx_pwr != other.rx_pwr: return False
+        if self.bias_current != other.bias_current: return False
+        if self.temperature != other.temperature: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("optical {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("tx_freq_lmda = ");
+                q.text("%#x" % self.tx_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("tx_offset = ");
+                q.text("%#x" % self.tx_offset)
+                q.text(","); q.breakable()
+                q.text("tx_grid_span = ");
+                q.text("%#x" % self.tx_grid_span)
+                q.text(","); q.breakable()
+                q.text("rx_freq_lmda = ");
+                q.text("%#x" % self.rx_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("rx_offset = ");
+                q.text("%#x" % self.rx_offset)
+                q.text(","); q.breakable()
+                q.text("rx_grid_span = ");
+                q.text("%#x" % self.rx_grid_span)
+                q.text(","); q.breakable()
+                q.text("tx_pwr = ");
+                q.text("%#x" % self.tx_pwr)
+                q.text(","); q.breakable()
+                q.text("rx_pwr = ");
+                q.text("%#x" % self.rx_pwr)
+                q.text(","); q.breakable()
+                q.text("bias_current = ");
+                q.text("%#x" % self.bias_current)
+                q.text(","); q.breakable()
+                q.text("temperature = ");
+                q.text("%#x" % self.temperature)
+            q.breakable()
+        q.text('}')
+
+port_stats_prop.subtypes[1] = optical
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/queue_desc_prop.py b/Fabric/Utilities/src/python/loxi/of14/queue_desc_prop.py
new file mode 100644
index 0000000..a9a70b5
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/queue_desc_prop.py
@@ -0,0 +1,239 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class queue_desc_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = queue_desc_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_desc_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_desc_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(queue_desc_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, exp_type=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.exp_type = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("exp_type = ");
+                q.text("%#x" % self.exp_type)
+            q.breakable()
+        q.text('}')
+
+queue_desc_prop.subtypes[65535] = experimenter
+
+class max_rate(queue_desc_prop):
+    type = 2
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = max_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("max_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_desc_prop.subtypes[2] = max_rate
+
+class min_rate(queue_desc_prop):
+    type = 1
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = min_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("min_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_desc_prop.subtypes[1] = min_rate
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/queue_stats_prop.py b/Fabric/Utilities/src/python/loxi/of14/queue_stats_prop.py
new file mode 100644
index 0000000..1e03c59
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/queue_stats_prop.py
@@ -0,0 +1,141 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class queue_stats_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = queue_stats_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_stats_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(queue_stats_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, exp_type=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.exp_type = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("exp_type = ");
+                q.text("%#x" % self.exp_type)
+            q.breakable()
+        q.text('}')
+
+queue_stats_prop.subtypes[65535] = experimenter
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/role_prop.py b/Fabric/Utilities/src/python/loxi/of14/role_prop.py
new file mode 100644
index 0000000..b88f06f
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/role_prop.py
@@ -0,0 +1,141 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class role_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = role_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = role_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(role_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, exp_type=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.exp_type = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("exp_type = ");
+                q.text("%#x" % self.exp_type)
+            q.breakable()
+        q.text('}')
+
+role_prop.subtypes[65535] = experimenter
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/table_mod_prop.py b/Fabric/Utilities/src/python/loxi/of14/table_mod_prop.py
new file mode 100644
index 0000000..f6c4292
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/table_mod_prop.py
@@ -0,0 +1,80 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class table_mod_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = table_mod_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_mod_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/util.py b/Fabric/Utilities/src/python/loxi/of14/util.py
new file mode 100644
index 0000000..fe23da1
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/util.py
@@ -0,0 +1,139 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+# Automatically generated by LOXI from template util.py
+# Do not modify
+
+import struct
+import loxi
+import const
+import common
+import action
+import instruction
+import oxm
+import action_id
+import instruction_id
+import meter_band
+
+def pretty_mac(mac):
+    return ':'.join(["%02x" % x for x in mac])
+
+def pretty_ipv4(v):
+    return "%d.%d.%d.%d" % ((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF)
+
+def pretty_flags(v, flag_names):
+    set_flags = []
+    for flag_name in flag_names:
+        flag_value = getattr(const, flag_name)
+        if v & flag_value == flag_value:
+            set_flags.append(flag_name)
+        elif v & flag_value:
+            set_flags.append('%s&%#x' % (flag_name, v & flag_value))
+        v &= ~flag_value
+    if v:
+        set_flags.append("%#x" % v)
+    return '|'.join(set_flags) or '0'
+
+
+def pretty_port(v):
+    named_ports = [(k,v2) for (k,v2) in const.__dict__.iteritems() if k.startswith('OFPP_')]
+    for (k, v2) in named_ports:
+        if v == v2:
+            return k
+    return v
+
+def pack_port_no(value):
+    return struct.pack("!L", value)
+
+def unpack_port_no(reader):
+    return reader.read("!L")[0]
+
+def pack_fm_cmd(value):
+    return struct.pack("!B", value)
+
+def unpack_fm_cmd(reader):
+    return reader.read("!B")[0]
+
+def init_wc_bmap():
+    return 0
+
+def pack_wc_bmap(value):
+    return struct.pack("!Q", value)
+
+def unpack_wc_bmap(reader):
+    return reader.read("!Q")[0]
+
+def init_match_bmap():
+    return 0
+
+def pack_match_bmap(value):
+    return struct.pack("!Q", value)
+
+def unpack_match_bmap(reader):
+    return reader.read("!Q")[0]
+
+MASK64 = (1 << 64) - 1
+
+def pack_bitmap_128(value):
+    x = 0l
+    for y in value:
+        x |= 1 << y
+    return struct.pack("!QQ", (x >> 64) & MASK64, x & MASK64)
+
+def unpack_bitmap_128(reader):
+    hi, lo = reader.read("!QQ")
+    x = (hi << 64) | lo
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_bitmap_512(value):
+    words = [0] * 8
+    for v in value:
+        assert v < 512
+        words[7-v/64] |= 1 << (v % 64)
+    return struct.pack("!8Q", *words)
+
+def unpack_bitmap_512(reader):
+    words = reader.read("!8Q")
+    x = 0l
+    for word in words:
+        x <<= 64
+        x |= word
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_checksum_128(value):
+    return struct.pack("!QQ", (value >> 64) & MASK64, value & MASK64)
+
+def unpack_checksum_128(reader):
+    hi, lo = reader.read("!QQ")
+    return (hi << 64) | lo
diff --git a/Fabric/Utilities/src/python/loxi/pp.py b/Fabric/Utilities/src/python/loxi/pp.py
new file mode 100644
index 0000000..f85d1da
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/pp.py
@@ -0,0 +1,266 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright 2013, Big Switch Networks, Inc.
+
+"""
+pp - port of Ruby's PP library
+Also based on Lindig, C., & GbR, G. D. (2000). Strictly Pretty.
+
+Example usage:
+>>> import pp.pp as pp
+>>> print pp([[1, 2], [3, 4]], maxwidth=15)
+[
+  [ 1, 2 ],
+  [ 3, 4 ]
+]
+"""
+import unittest
+from contextlib import contextmanager
+
+def pp(obj, maxwidth=79):
+    """
+    Pretty-print the given object.
+    """
+    ctx = PrettyPrinter(maxwidth=maxwidth)
+    ctx.pp(obj)
+    return str(ctx)
+
+
+## Pretty-printers for builtin classes
+
+def pretty_print_list(pp, obj):
+    with pp.group():
+        pp.text('[')
+        with pp.indent(2):
+            for v in obj:
+                if not pp.first(): pp.text(',')
+                pp.breakable()
+                pp.pp(v)
+        pp.breakable()
+        pp.text(']')
+
+def pretty_print_dict(pp, obj):
+    with pp.group():
+        pp.text('{')
+        with pp.indent(2):
+            for (k, v) in sorted(obj.items()):
+                if not pp.first(): pp.text(',')
+                pp.breakable()
+                pp.pp(k)
+                pp.text(': ')
+                pp.pp(v)
+        pp.breakable()
+        pp.text('}')
+
+pretty_printers = {
+    list: pretty_print_list,
+    dict: pretty_print_dict,
+}
+
+
+## Implementation
+
+class PrettyPrinter(object):
+    def __init__(self, maxwidth):
+        self.maxwidth = maxwidth
+        self.cur_indent = 0
+        self.root_group = Group()
+        self.group_stack = [self.root_group]
+
+    def current_group(self):
+        return self.group_stack[-1]
+
+    def text(self, s):
+        self.current_group().append(str(s))
+
+    def breakable(self, sep=' '):
+        self.current_group().append(Breakable(sep, self.cur_indent))
+
+    def first(self):
+        return self.current_group().first()
+
+    @contextmanager
+    def indent(self, n):
+        self.cur_indent += n
+        yield
+        self.cur_indent -= n
+
+    @contextmanager
+    def group(self):
+        self.group_stack.append(Group())
+        yield
+        new_group = self.group_stack.pop()
+        self.current_group().append(new_group)
+
+    def pp(self, obj):
+        if hasattr(obj, "pretty_print"):
+            obj.pretty_print(self)
+        elif type(obj) in pretty_printers:
+            pretty_printers[type(obj)](self, obj)
+        else:
+            self.text(repr(obj))
+
+    def __str__(self):
+        return self.root_group.render(0, self.maxwidth)
+
+class Group(object):
+    __slots__ = ["fragments", "length", "_first"]
+
+    def __init__(self):
+        self.fragments = []
+        self.length = 0
+        self._first = True
+
+    def append(self, x):
+        self.fragments.append(x)
+        self.length += len(x)
+
+    def first(self):
+        if self._first:
+            self._first = False
+            return True
+        return False
+
+    def __len__(self):
+        return self.length
+
+    def render(self, curwidth, maxwidth):
+        dobreak = len(self) > (maxwidth - curwidth)
+
+        a = []
+        for x in self.fragments:
+            if isinstance(x, Breakable):
+                if dobreak:
+                    a.append('\n')
+                    a.append(' ' * x.indent)
+                    curwidth = 0
+                else:
+                    a.append(x.sep)
+            elif isinstance(x, Group):
+                a.append(x.render(curwidth, maxwidth))
+            else:
+                a.append(x)
+            curwidth += len(a[-1])
+        return ''.join(a)
+
+class Breakable(object):
+    __slots__ = ["sep", "indent"]
+
+    def __init__(self, sep, indent):
+        self.sep = sep
+        self.indent = indent
+
+    def __len__(self):
+        return len(self.sep)
+
+
+## Tests
+
+class TestPP(unittest.TestCase):
+    def test_scalars(self):
+        self.assertEquals(pp(1), "1")
+        self.assertEquals(pp("foo"), "'foo'")
+
+    def test_hash(self):
+        expected = """{ 1: 'a', 'b': 2 }"""
+        self.assertEquals(pp(eval(expected)), expected)
+        expected = """\
+{
+  1: 'a',
+  'b': 2
+}"""
+        self.assertEquals(pp(eval(expected), maxwidth=0), expected)
+
+    def test_array(self):
+        expected = """[ 1, 'a', 2 ]"""
+        self.assertEquals(pp(eval(expected)), expected)
+        expected = """\
+[
+  1,
+  'a',
+  2
+]"""
+        self.assertEquals(pp(eval(expected), maxwidth=0), expected)
+
+    def test_nested(self):
+        expected = """[ [ 1, 2 ], [ 3, 4 ] ]"""
+        self.assertEquals(pp(eval(expected)), expected)
+        expected = """\
+[
+  [
+    1,
+    2
+  ],
+  [
+    3,
+    4
+  ]
+]"""
+        self.assertEquals(pp(eval(expected), maxwidth=0), expected)
+
+    def test_breaking(self):
+        expected = """\
+[
+  [ 1, 2 ],
+  'abcdefghijklmnopqrstuvwxyz'
+]"""
+        self.assertEquals(pp(eval(expected), maxwidth=24), expected)
+        expected = """\
+[
+  [ 'abcd', 2 ],
+  [ '0123456789' ],
+  [
+    '0123456789',
+    'abcdefghij'
+  ],
+  [ 'abcdefghijklmnop' ],
+  [
+    'abcdefghijklmnopq'
+  ],
+  { 'k': 'v' },
+  {
+    1: [ 2, [ 3, 4 ] ],
+    'foo': 'abcdefghijklmnop'
+  }
+]"""
+        self.assertEquals(pp(eval(expected), maxwidth=24), expected)
+        expected = """\
+[
+  [ 1, 2 ],
+  [ 3, 4 ]
+]"""
+        self.assertEquals(pp(eval(expected), maxwidth=15), expected)
+
+    # This is an edge case where our simpler algorithm breaks down.
+    @unittest.expectedFailure
+    def test_greedy_breaking(self):
+        expected = """\
+abc def
+ghijklmnopqrstuvwxyz\
+"""
+        pp = PrettyPrinter(maxwidth=8)
+        pp.text("abc")
+        with pp.group():
+            pp.breakable()
+        pp.text("def")
+        with pp.group():
+            pp.breakable()
+        pp.text("ghijklmnopqrstuvwxyz")
+        self.assertEquals(str(pp), expected)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Fabric/Utilities/src/python/oftest/__init__.py b/Fabric/Utilities/src/python/oftest/__init__.py
new file mode 100644
index 0000000..2be5038
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/__init__.py
@@ -0,0 +1,56 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+'''Docstring to silence pylint; ignores --ignore option for __init__.py'''
+import sys
+import os
+import logging
+
+# Global config dictionary
+# Populated by oft.
+config = {}
+
+# Global DataPlane instance used by all tests.
+# Populated by oft.
+dataplane_instance = None
+
+def open_logfile(name):
+    """
+    (Re)open logfile
+
+    When using a log directory a new logfile is created for each test. The same
+    code is used to implement a single logfile in the absence of --log-dir.
+    """
+
+    _format = "%(asctime)s.%(msecs)03d  %(name)-10s: %(levelname)-8s: %(message)s"
+    _datefmt = "%H:%M:%S"
+
+    if config["log_dir"] != None:
+        filename = os.path.join(config["log_dir"], name) + ".log"
+    else:
+        filename = config["log_file"]
+
+    logger = logging.getLogger()
+
+    # Remove any existing handlers
+    for handler in logger.handlers:
+        logger.removeHandler(handler)
+        handler.close()
+
+    # Add a new handler
+    handler = logging.FileHandler(filename, mode='a')
+    handler.setFormatter(logging.Formatter(_format, _datefmt))
+    logger.addHandler(handler)
diff --git a/Fabric/Utilities/src/python/oftest/afpacket.py b/Fabric/Utilities/src/python/oftest/afpacket.py
new file mode 100644
index 0000000..a891d85
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/afpacket.py
@@ -0,0 +1,128 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+AF_PACKET receive support
+
+When VLAN offload is enabled on the NIC Linux will not deliver the VLAN tag
+in the data returned by recv. Instead, it delivers the VLAN TCI in a control
+message. Python 2.x doesn't have built-in support for recvmsg, so we have to
+use ctypes to call it. The recv function exported by this module reconstructs
+the VLAN tag if it was offloaded.
+"""
+
+import socket
+import struct
+from ctypes import *
+
+ETH_P_8021Q = 0x8100
+SOL_PACKET = 263
+PACKET_AUXDATA = 8
+TP_STATUS_VLAN_VALID = 1 << 4
+
+class struct_iovec(Structure):
+    _fields_ = [
+        ("iov_base", c_void_p),
+        ("iov_len", c_size_t),
+    ]
+
+class struct_msghdr(Structure):
+    _fields_ = [
+        ("msg_name", c_void_p),
+        ("msg_namelen", c_uint32),
+        ("msg_iov", POINTER(struct_iovec)),
+        ("msg_iovlen", c_size_t),
+        ("msg_control", c_void_p),
+        ("msg_controllen", c_size_t),
+        ("msg_flags", c_int),
+    ]
+
+class struct_cmsghdr(Structure):
+    _fields_ = [
+        ("cmsg_len", c_size_t),
+        ("cmsg_level", c_int),
+        ("cmsg_type", c_int),
+    ]
+
+class struct_tpacket_auxdata(Structure):
+    _fields_ = [
+        ("tp_status", c_uint),
+        ("tp_len", c_uint),
+        ("tp_snaplen", c_uint),
+        ("tp_mac", c_ushort),
+        ("tp_net", c_ushort),
+        ("tp_vlan_tci", c_ushort),
+        ("tp_padding", c_ushort),
+    ]
+
+libc = CDLL("libc.so.6")
+recvmsg = libc.recvmsg
+recvmsg.argtypes = [c_int, POINTER(struct_msghdr), c_int]
+recvmsg.retype = c_int
+
+def enable_auxdata(sk):
+    """
+    Ask the kernel to return the VLAN tag in a control message
+
+    Must be called on the socket before afpacket.recv.
+    """
+    sk.setsockopt(SOL_PACKET, PACKET_AUXDATA, 1)
+
+def recv(sk, bufsize):
+    """
+    Receive a packet from an AF_PACKET socket
+    @sk Socket
+    @bufsize Maximum packet size
+    """
+    buf = create_string_buffer(bufsize)
+
+    ctrl_bufsize = sizeof(struct_cmsghdr) + sizeof(struct_tpacket_auxdata) + sizeof(c_size_t)
+    ctrl_buf = create_string_buffer(ctrl_bufsize)
+
+    iov = struct_iovec()
+    iov.iov_base = cast(buf, c_void_p)
+    iov.iov_len = bufsize
+
+    msghdr = struct_msghdr()
+    msghdr.msg_name = None
+    msghdr.msg_namelen = 0
+    msghdr.msg_iov = pointer(iov)
+    msghdr.msg_iovlen = 1
+    msghdr.msg_control = cast(ctrl_buf, c_void_p)
+    msghdr.msg_controllen = ctrl_bufsize
+    msghdr.msg_flags = 0
+
+    rv = recvmsg(sk.fileno(), byref(msghdr), 0)
+    if rv < 0:
+        raise RuntimeError("recvmsg failed: rv=%d", rv)
+
+    # The kernel only delivers control messages we ask for. We
+    # only enabled PACKET_AUXDATA, so we can assume it's the
+    # only control message.
+    assert msghdr.msg_controllen >= sizeof(struct_cmsghdr)
+
+    cmsghdr = struct_cmsghdr.from_buffer(ctrl_buf) # pylint: disable=E1101
+    assert cmsghdr.cmsg_level == SOL_PACKET
+    assert cmsghdr.cmsg_type == PACKET_AUXDATA
+
+    auxdata = struct_tpacket_auxdata.from_buffer(ctrl_buf, sizeof(struct_cmsghdr)) # pylint: disable=E1101
+
+    if auxdata.tp_vlan_tci != 0 or auxdata.tp_status & TP_STATUS_VLAN_VALID:
+        # Insert VLAN tag
+        tag = struct.pack("!HH", ETH_P_8021Q, auxdata.tp_vlan_tci)
+        return buf.raw[:12] + tag + buf.raw[12:rv]
+    else:
+        return buf.raw[:rv]
diff --git a/Fabric/Utilities/src/python/oftest/base_tests.py b/Fabric/Utilities/src/python/oftest/base_tests.py
new file mode 100755
index 0000000..7eb68bc
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/base_tests.py
@@ -0,0 +1,162 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Base classes for test cases
+
+Tests will usually inherit from one of these classes to have the controller
+and/or dataplane automatically set up.
+"""
+
+import logging
+import unittest
+import os
+
+import oftest
+from oftest import config
+import oftest.controller as controller
+import oftest.dataplane as dataplane
+import ofp
+from ofdpa_utils import *
+
+class BaseTest(unittest.TestCase):
+    def __str__(self):
+        return self.id().replace('.runTest', '')
+
+    def setUp(self):
+        if config["force_ofdpa_restart"]:
+            logging.info("Restarting OFDPA")
+            forceOfdpaRestart( config["force_ofdpa_restart"]);
+        oftest.open_logfile(str(self))
+        logging.info("** START TEST CASE " + str(self))
+
+    def tearDown(self):
+        logging.info("** END TEST CASE " + str(self))
+        if config["force_ofdpa_restart"]:
+            forceOfdpaStop( config["force_ofdpa_restart"]);
+
+
+class SimpleProtocol(BaseTest):
+    """
+    Root class for setting up the controller
+    """
+
+    def setUp(self):
+        BaseTest.setUp(self)
+        self.controller = controller.Controller(
+            switch=config["switch_ip"],
+            host=config["controller_host"],
+            port=config["controller_port"])
+        self.controller.start()
+
+        try:
+            #@todo Add an option to wait for a pkt transaction to ensure version
+            # compatibilty?
+            self.controller.connect(timeout=20)
+
+            # By default, respond to echo requests
+            self.controller.keep_alive = True
+            if not self.controller.active:
+                raise Exception("Controller startup failed")
+            if self.controller.switch_addr is None:
+                raise Exception("Controller startup failed (no switch addr)")
+            logging.info("Connected " + str(self.controller.switch_addr))
+            request = ofp.message.features_request()
+            reply, pkt = self.controller.transact(request)
+            self.assertTrue(reply is not None,
+                            "Did not complete features_request for handshake")
+            if reply.version == 1:
+                self.supported_actions = reply.actions
+                logging.info("Supported actions: " + hex(self.supported_actions))
+        except:
+            self.controller.kill()
+            del self.controller
+            raise
+
+    def inheritSetup(self, parent):
+        """
+        Inherit the setup of a parent
+
+        This allows running at test from within another test.  Do the
+        following:
+
+        sub_test = SomeTestClass()  # Create an instance of the test class
+        sub_test.inheritSetup(self) # Inherit setup of parent
+        sub_test.runTest()          # Run the test
+
+        Normally, only the parent's setUp and tearDown are called and
+        the state after the sub_test is run must be taken into account
+        by subsequent operations.
+        """
+        logging.info("** Setup " + str(self) + " inheriting from "
+                          + str(parent))
+        self.controller = parent.controller
+        self.supported_actions = parent.supported_actions
+        
+    def tearDown(self):
+        self.controller.shutdown()
+        self.controller.join()
+        del self.controller
+        BaseTest.tearDown(self)
+
+    def assertTrue(self, cond, msg):
+        if not cond:
+            logging.error("** FAILED ASSERTION: " + msg)
+        unittest.TestCase.assertTrue(self, cond, msg)
+
+class SimpleDataPlane(SimpleProtocol):
+    """
+    Root class that sets up the controller and dataplane
+    """
+    def setUp(self):
+        SimpleProtocol.setUp(self)
+        self.dataplane = oftest.dataplane_instance
+        self.dataplane.flush()
+        if config["log_dir"] != None:
+            filename = os.path.join(config["log_dir"], str(self)) + ".pcap"
+            self.dataplane.start_pcap(filename)
+
+    def inheritSetup(self, parent):
+        """
+        Inherit the setup of a parent
+
+        See SimpleProtocol.inheritSetup
+        """
+        SimpleProtocol.inheritSetup(self, parent)
+        self.dataplane = parent.dataplane
+
+    def tearDown(self):
+        if config["log_dir"] != None:
+            self.dataplane.stop_pcap()
+        SimpleProtocol.tearDown(self)
+
+class DataPlaneOnly(BaseTest):
+    """
+    Root class that sets up only the dataplane
+    """
+
+    def setUp(self):
+        BaseTest.setUp(self)
+        self.dataplane = oftest.dataplane_instance
+        self.dataplane.flush()
+        if config["log_dir"] != None:
+            filename = os.path.join(config["log_dir"], str(self)) + ".pcap"
+            self.dataplane.start_pcap(filename)
+
+    def tearDown(self):
+        if config["log_dir"] != None:
+            self.dataplane.stop_pcap()
+        BaseTest.tearDown(self)
diff --git a/Fabric/Utilities/src/python/oftest/controller.py b/Fabric/Utilities/src/python/oftest/controller.py
new file mode 100755
index 0000000..e52bfbe
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/controller.py
@@ -0,0 +1,767 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+OpenFlow Test Framework
+
+Controller class
+
+Provide the interface to the control channel to the switch under test.  
+
+Class inherits from thread so as to run in background allowing
+asynchronous callbacks (if needed, not required).  Also supports
+polling.
+
+The controller thread maintains a queue.  Incoming messages that
+are not handled by a callback function are placed in this queue for 
+poll calls.  
+
+Callbacks and polling support specifying the message type
+
+@todo Support transaction semantics via xid
+@todo Support select and listen on an administrative socket (or
+use a timeout to support clean shutdown).
+
+Currently only one connection is accepted during the life of
+the controller.   There seems
+to be no clean way to interrupt an accept call.  Using select that also listens
+on an administrative socket and can shut down the socket might work.
+
+"""
+
+import sys
+import os
+import socket
+import time
+import struct
+import select
+import logging
+from threading import Thread
+from threading import Lock
+from threading import Condition
+
+import ofutils
+import loxi
+
+# Configured openflow version
+import ofp as cfg_ofp
+
+FILTER = ''.join( [ (len( repr( chr( x ) ) ) == 3) and chr( x ) or '.'
+                    for x in range( 256 ) ] )
+
+
+def hex_dump_buffer( src, length=16 ):
+    """
+    Convert src to a hex dump string and return the string
+    @param src The source buffer
+    @param length The number of bytes shown in each line
+    @returns A string showing the hex dump
+    """
+    result = [ "\n" ]
+    for i in xrange( 0, len( src ), length ):
+        chars = src[ i:i + length ]
+        hex = ' '.join( [ "%02x" % ord( x ) for x in chars ] )
+        printable = ''.join( [ "%s" % ((ord( x ) <= 127 and
+                                        FILTER[ ord( x ) ]) or '.') for x in
+                               chars ] )
+        result.append( "%04x  %-*s  %s\n" % (i, length * 3, hex, printable) )
+    return ''.join( result )
+
+
+##@todo Find a better home for these identifiers (controller)
+RCV_SIZE_DEFAULT = 32768
+LISTEN_QUEUE_SIZE = 1
+
+
+class Controller( Thread ):
+    """
+    Class abstracting the control interface to the switch.  
+
+    For receiving messages, two mechanism will be implemented.  First,
+    query the interface with poll.  Second, register to have a
+    function called by message type.  The callback is passed the
+    message type as well as the raw packet (or message object)
+
+    One of the main purposes of this object is to translate between network 
+    and host byte order.  'Above' this object, things should be in host
+    byte order.
+
+    @todo Consider using SocketServer for listening socket
+    @todo Test transaction code
+
+    @var rcv_size The receive size to use for receive calls
+    @var max_pkts The max size of the receive queue
+    @var keep_alive If true, listen for echo requests and respond w/
+    echo replies
+    @var initial_hello If true, will send a hello message immediately
+    upon connecting to the switch
+    @var switch If not None, do an active connection to the switch
+    @var host The host to use for connect
+    @var port The port to connect on 
+    @var packets_total Total number of packets received
+    @var packets_expired Number of packets popped from queue as queue full
+    @var packets_handled Number of packets handled by something
+    @var dbg_state Debug indication of state
+    """
+
+    def __init__( self, switch=None, host='127.0.0.1', port=6653, max_pkts=1024,
+                  force=False ):
+        Thread.__init__( self )
+        # Socket related
+        self.rcv_size = RCV_SIZE_DEFAULT
+        self.listen_socket = None
+        self.switch_socket = None
+        self.switch_addr = None
+        self.connect_cv = Condition( )
+        self.message_cv = Condition( )
+        self.tx_lock = Lock( )
+
+        # Used to wake up the event loop from another thread
+        self.waker = ofutils.EventDescriptor( )
+
+        # Counters
+        self.socket_errors = 0
+        self.parse_errors = 0
+        self.packets_total = 0
+        self.packets_expired = 0
+        self.packets_handled = 0
+        self.poll_discards = 0
+
+        # State
+        self.sync = Lock( )
+        self.handlers = { }
+        self.keep_alive = False
+        self.active = True
+        self.initial_hello = True
+
+        # OpenFlow message/packet queue
+        # Protected by the packets_cv lock / condition variable
+        self.packets = [ ]
+        self.packets_cv = Condition( )
+        self.packet_in_count = 0
+
+        # Settings
+        self.max_pkts = max_pkts
+        self.switch = switch
+        self.passive = not self.switch
+        self.force = force
+        self.host = host
+        self.port = port
+        self.dbg_state = "init"
+        self.logger = logging.getLogger( "controller" )
+        self.filter_packet_in = False  # Drop "excessive" packet ins
+        self.pkt_in_run = 0  # Count on run of packet ins
+        self.pkt_in_filter_limit = 50  # Count on run of packet ins
+        self.pkt_in_dropped = 0  # Total dropped packet ins
+        self.transact_to = 15  # Transact timeout default value; add to config
+
+        # Transaction and message type waiting variables 
+        #   xid_cv: Condition variable (semaphore) for packet waiters
+        #   xid: Transaction ID being waited on
+        #   xid_response: Transaction response message
+        self.xid_cv = Condition( )
+        self.xid = None
+        self.xid_response = None
+
+        self.buffered_input = ""
+
+        # Create listen socket
+        if self.passive:
+            self.logger.info( "Create/listen at " + self.host + ":" +
+                              str( self.port ) )
+            ai = socket.getaddrinfo( self.host, self.port, socket.AF_UNSPEC,
+                                     socket.SOCK_STREAM, 0, socket.AI_PASSIVE )
+            # Use first returned addrinfo
+            (family, socktype, proto, name, sockaddr) = ai[ 0 ]
+            self.listen_socket = socket.socket( family, socktype )
+            self.listen_socket.setsockopt( socket.SOL_SOCKET,
+                                           socket.SO_REUSEADDR, 1 )
+            self.listen_socket.bind( sockaddr )
+            self.listen_socket.listen( LISTEN_QUEUE_SIZE )
+
+    def filter_packet( self, rawmsg, hdr ):
+        """
+        Check if packet should be filtered
+
+        Currently filters packet in messages
+        @return Boolean, True if packet should be dropped
+        """
+        # XXX didn't actually check for packet-in...
+        return False
+        # Add check for packet in and rate limit
+        if self.filter_packet_in:
+            # If we were dropping packets, report number dropped
+            # TODO dont drop expected packet ins
+            if self.pkt_in_run > self.pkt_in_filter_limit:
+                self.logger.debug( "Dropped %d packet ins (%d total)"
+                                   % ((self.pkt_in_run -
+                                       self.pkt_in_filter_limit),
+                                      self.pkt_in_dropped) )
+            self.pkt_in_run = 0
+
+        return False
+
+    def _pkt_handle( self, pkt ):
+        """
+        Check for all packet handling conditions
+
+        Parse and verify message 
+        Check if XID matches something waiting
+        Check if message is being expected for a poll operation
+        Check if keep alive is on and message is an echo request
+        Check if any registered handler wants the packet
+        Enqueue if none of those conditions is met
+
+        an echo request in case keep_alive is true, followed by
+        registered message handlers.
+        @param pkt The raw packet (string) which may contain multiple OF msgs
+        """
+
+        # snag any left over data from last read()
+        pkt = self.buffered_input + pkt
+        self.buffered_input = ""
+
+        # Process each of the OF msgs inside the pkt
+        offset = 0
+        while offset < len( pkt ):
+            if offset + 8 > len( pkt ):
+                break
+
+            # Parse the header to get type
+            hdr_version, hdr_type, hdr_length, hdr_xid = cfg_ofp.message.parse_header(
+                    pkt[ offset: ] )
+
+            # Use loxi to resolve to ofp of matching version
+            ofp = loxi.protocol( hdr_version )
+
+            # Extract the raw message bytes
+            if (offset + hdr_length) > len( pkt ):
+                break
+            rawmsg = pkt[ offset: offset + hdr_length ]
+            offset += hdr_length
+
+            # if self.filter_packet(rawmsg, hdr):
+            #    continue
+
+            msg = ofp.message.parse_message( rawmsg )
+            if not msg:
+                self.parse_errors += 1
+                self.logger.warn( "Could not parse message" )
+                continue
+
+            self.logger.debug( "Msg in: version %d class %s len %d xid %d",
+                               hdr_version, type( msg ).__name__, hdr_length,
+                               hdr_xid )
+
+            with self.sync:
+                # Check if transaction is waiting
+                with self.xid_cv:
+                    if self.xid and hdr_xid == self.xid:
+                        self.logger.debug(
+                                "Matched expected XID " + str( hdr_xid ) )
+                        self.xid_response = (msg, rawmsg)
+                        self.xid = None
+                        self.xid_cv.notify( )
+                        continue
+
+                # Check if keep alive is set; if so, respond to echo requests
+                if self.keep_alive:
+                    if hdr_type == ofp.OFPT_ECHO_REQUEST:
+                        self.logger.debug( "Responding to echo request" )
+                        rep = ofp.message.echo_reply( )
+                        rep.xid = hdr_xid
+                        # Ignoring additional data
+                        self.message_send( rep )
+                        continue
+
+                # Generalize to counters for all packet types?
+                if msg.type == ofp.OFPT_PACKET_IN:
+                    self.packet_in_count += 1
+
+                # Log error messages
+                if isinstance( msg, ofp.message.error_msg ):
+                    # pylint: disable=E1103
+                    if msg.err_type in ofp.ofp_error_type_map:
+                        type_str = ofp.ofp_error_type_map[ msg.err_type ]
+                        if msg.err_type == ofp.OFPET_HELLO_FAILED:
+                            code_map = ofp.ofp_hello_failed_code_map
+                        elif msg.err_type == ofp.OFPET_BAD_REQUEST:
+                            code_map = ofp.ofp_bad_request_code_map
+                        elif msg.err_type == ofp.OFPET_BAD_ACTION:
+                            code_map = ofp.ofp_bad_action_code_map
+                        elif msg.err_type == ofp.OFPET_FLOW_MOD_FAILED:
+                            code_map = ofp.ofp_flow_mod_failed_code_map
+                        elif msg.err_type == ofp.OFPET_PORT_MOD_FAILED:
+                            code_map = ofp.ofp_port_mod_failed_code_map
+                        elif msg.err_type == ofp.OFPET_QUEUE_OP_FAILED:
+                            code_map = ofp.ofp_queue_op_failed_code_map
+                        else:
+                            code_map = None
+
+                        if code_map and msg.code in code_map:
+                            code_str = code_map[ msg.code ]
+                        else:
+                            code_str = "unknown"
+                    else:
+                        type_str = "unknown"
+                        code_str = "unknown"
+                    self.logger.warn(
+                            "Received error message: xid=%d type=%s (%d) code=%s (%d)",
+                            hdr_xid, type_str, msg.err_type, code_str,
+                            msg.code )
+
+                # Now check for message handlers; preference is given to
+                # handlers for a specific packet
+                handled = False
+                if hdr_type in self.handlers.keys( ):
+                    handled = self.handlers[ hdr_type ]( self, msg, rawmsg )
+                if not handled and ("all" in self.handlers.keys( )):
+                    handled = self.handlers[ "all" ]( self, msg, rawmsg )
+
+                if not handled:  # Not handled, enqueue
+                    with self.packets_cv:
+                        if len( self.packets ) >= self.max_pkts:
+                            self.packets.pop( 0 )
+                            self.packets_expired += 1
+                        self.packets.append( (msg, rawmsg) )
+                        self.packets_cv.notify_all( )
+                    self.packets_total += 1
+                else:
+                    self.packets_handled += 1
+                    self.logger.debug( "Message handled by callback" )
+
+        # end of 'while offset < len(pkt)'
+        #   note that if offset = len(pkt), this is
+        #   appends a harmless empty string
+        self.buffered_input += pkt[ offset: ]
+
+    def _socket_ready_handle( self, s ):
+        """
+        Handle an input-ready socket
+
+        @param s The socket object that is ready
+        @returns 0 on success, -1 on error
+        """
+
+        if self.passive and s and s == self.listen_socket:
+            if self.switch_socket:
+                self.logger.warning(
+                        "Ignoring incoming connection; already connected to switch" )
+                (sock, addr) = self.listen_socket.accept( )
+                sock.close( )
+                return 0
+
+            try:
+                (sock, addr) = self.listen_socket.accept( )
+            except:
+                self.logger.warning( "Error on listen socket accept" )
+                return -1
+            self.logger.info( self.host + ":" + str(
+                    self.port ) + ": Incoming connection from " + str( addr ) )
+
+            with self.connect_cv:
+                (self.switch_socket, self.switch_addr) = (sock, addr)
+                self.switch_socket.setsockopt( socket.IPPROTO_TCP,
+                                               socket.TCP_NODELAY, True )
+                if self.initial_hello:
+                    self.message_send( cfg_ofp.message.hello( ) )
+                self.connect_cv.notify( )  # Notify anyone waiting
+
+            # Prevent further connections
+            self.listen_socket.close( )
+            self.listen_socket = None
+        elif s and s == self.switch_socket:
+            for idx in range( 3 ):  # debug: try a couple of times
+                try:
+                    pkt = self.switch_socket.recv( self.rcv_size )
+                except:
+                    self.logger.warning( "Error on switch read" )
+                    return -1
+
+                if not self.active:
+                    return 0
+
+                if len( pkt ) == 0:
+                    self.logger.warning( "Zero-length switch read, %d" % idx )
+                else:
+                    break
+
+            if len( pkt ) == 0:  # Still no packet
+                self.logger.warning( "Zero-length switch read; closing cxn" )
+                self.logger.info( str( self ) )
+                return -1
+
+            self._pkt_handle( pkt )
+        elif s and s == self.waker:
+            self.waker.wait( )
+        else:
+            self.logger.error( "Unknown socket ready: " + str( s ) )
+            return -1
+
+        return 0
+
+    def active_connect( self ):
+        """
+        Actively connect to a switch IP addr
+        """
+        try:
+            self.logger.info( "Trying active connection to %s" % self.switch )
+            soc = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+            soc.connect( (self.switch, self.port) )
+            self.logger.info( "Connected to " + self.switch + " on " +
+                              str( self.port ) )
+            soc.setsockopt( socket.IPPROTO_TCP, socket.TCP_NODELAY, True )
+            self.switch_addr = (self.switch, self.port)
+            return soc
+        except (StandardError, socket.error), e:
+            self.logger.error( "Could not connect to %s at %d:: %s" %
+                               (self.switch, self.port, str( e )) )
+        return None
+
+    def wakeup( self ):
+        """
+        Wake up the event loop, presumably from another thread.
+        """
+        self.waker.notify( )
+
+    def sockets( self ):
+        """
+        Return list of sockets to select on.
+        """
+        socs = [ self.listen_socket, self.switch_socket, self.waker ]
+        return [ x for x in socs if x ]
+
+    def run( self ):
+        """
+        Activity function for class
+
+        Assumes connection to switch already exists.  Listens on
+        switch_socket for messages until an error (or zero len pkt)
+        occurs.
+
+        When there is a message on the socket, check for handlers; queue the
+        packet if no one handles the packet.
+
+        See note for controller describing the limitation of a single
+        connection for now.
+        """
+
+        self.dbg_state = "running"
+
+        while self.active:
+            try:
+                sel_in, sel_out, sel_err = \
+                    select.select( self.sockets( ), [ ], self.sockets( ), 1 )
+            except:
+                print sys.exc_info( )
+                self.logger.error( "Select error, disconnecting" )
+                self.disconnect( )
+
+            for s in sel_err:
+                self.logger.error(
+                        "Got socket error on: " + str( s ) + ", disconnecting" )
+                self.disconnect( )
+
+            for s in sel_in:
+                if self._socket_ready_handle( s ) == -1:
+                    self.disconnect( )
+
+        # End of main loop
+        self.dbg_state = "closing"
+        self.logger.info( "Exiting controller thread" )
+        self.shutdown( )
+
+    def connect( self, timeout=-1 ):
+        """
+        Connect to the switch
+
+        @param timeout Block for up to timeout seconds. Pass -1 for the default.
+        @return Boolean, True if connected
+        """
+
+        if not self.passive:  # Do active connection now
+            self.logger.info( "Attempting to connect to %s on port %s" %
+                                  (self.switch, str( self.port )) )
+            soc = self.active_connect( )
+            if soc:
+                self.logger.info( "Connected to %s", self.switch )
+                self.dbg_state = "running"
+                self.switch_socket = soc
+                self.wakeup( )
+                with self.connect_cv:
+                    if self.initial_hello:
+                        self.message_send( cfg_ofp.message.hello( ) )
+                    self.connect_cv.notify( )  # Notify anyone waiting
+            else:
+                self.logger.error( "Could not actively connect to switch %s",
+                                   self.switch )
+                self.active = False
+        else:
+            with self.connect_cv:
+                ofutils.timed_wait( self.connect_cv, lambda: self.switch_socket,
+                                    timeout=timeout )
+
+        return self.switch_socket is not None
+
+    def disconnect( self, timeout=-1 ):
+        """
+        If connected to a switch, disconnect.
+        """
+        if self.switch_socket:
+            self.switch_socket.close( )
+            self.switch_socket = None
+            self.switch_addr = None
+            with self.packets_cv:
+                self.packets = [ ]
+            with self.connect_cv:
+                self.connect_cv.notifyAll( )
+
+    def wait_disconnected( self, timeout=-1 ):
+        """
+        @param timeout Block for up to timeout seconds. Pass -1 for the default.
+        @return Boolean, True if disconnected
+        """
+
+        with self.connect_cv:
+            ofutils.timed_wait( self.connect_cv,
+                                lambda: True if not self.switch_socket else None,
+                                timeout=timeout )
+        return self.switch_socket is None
+
+    def kill( self ):
+        """
+        Force the controller thread to quit
+        """
+        self.active = False
+        self.wakeup( )
+        self.join( )
+
+    def shutdown( self ):
+        """
+        Shutdown the controller closing all sockets
+
+        @todo Might want to synchronize shutdown with self.sync...
+        """
+
+        self.active = False
+        try:
+            self.switch_socket.shutdown( socket.SHUT_RDWR )
+        except:
+            self.logger.info( "Ignoring switch soc shutdown error" )
+        self.switch_socket = None
+
+        try:
+            self.listen_socket.shutdown( socket.SHUT_RDWR )
+        except:
+            self.logger.info( "Ignoring listen soc shutdown error" )
+        self.listen_socket = None
+
+        # Wakeup condition variables on which controller may be wait
+        with self.xid_cv:
+            self.xid_cv.notifyAll( )
+
+        with self.connect_cv:
+            self.connect_cv.notifyAll( )
+
+        self.wakeup( )
+        self.dbg_state = "down"
+
+    def register( self, msg_type, handler ):
+        """
+        Register a callback to receive a specific message type.
+
+        Only one handler may be registered for a given message type.
+
+        WARNING:  A lock is held during the handler call back, so 
+        the handler should not make any blocking calls
+
+        @param msg_type The type of message to receive.  May be DEFAULT 
+        for all non-handled packets.  The special type, the string "all"
+        will send all packets to the handler.
+        @param handler The function to call when a message of the given 
+        type is received.
+        """
+        # Should check type is valid
+        if not handler and msg_type in self.handlers.keys( ):
+            del self.handlers[ msg_type ]
+            return
+        self.handlers[ msg_type ] = handler
+
+    def poll( self, exp_msg=None, timeout=-1 ):
+        """
+        Wait for the next OF message received from the switch.
+
+        @param exp_msg If set, return only when this type of message 
+        is received (unless timeout occurs).
+
+        @param timeout Maximum number of seconds to wait for the message.
+        Pass -1 for the default timeout.
+
+        @retval A pair (msg, pkt) where msg is a message object and pkt
+        the string representing the packet as received from the socket.
+        This allows additional parsing by the receiver if necessary.
+
+        The data members in the message are in host endian order.
+        If an error occurs, (None, None) is returned
+        """
+
+        if exp_msg is None:
+            self.logger.warn( "DEPRECATED polling for any message class" )
+            klass = None
+        elif isinstance( exp_msg, int ):
+            klass = cfg_ofp.message.message.subtypes[ exp_msg ]
+        elif issubclass( exp_msg, loxi.OFObject ):
+            klass = exp_msg
+        else:
+            raise ValueError( "Unexpected exp_msg argument %r" % exp_msg )
+
+        self.logger.debug( "Polling for %s", klass.__name__ )
+
+        # Take the packet from the queue
+        def grab( ):
+            for i, (msg, pkt) in enumerate( self.packets ):
+                if klass is None or isinstance( msg, klass ):
+                    self.logger.debug( "Got %s message",
+                                       msg.__class__.__name__ )
+                    return self.packets.pop( i )
+            # Not found
+            self.logger.debug( "%s message not in queue", klass.__name__ )
+            return None
+
+        with self.packets_cv:
+            ret = ofutils.timed_wait( self.packets_cv, grab, timeout=timeout )
+
+        if ret != None:
+            (msg, pkt) = ret
+            return (msg, pkt)
+        else:
+            return (None, None)
+
+    def transact( self, msg, timeout=-1 ):
+        """
+        Run a message transaction with the switch
+
+        Send the message in msg and wait for a reply with a matching
+        transaction id.  Transactions have the highest priority in
+        received message handling.
+
+        @param msg The message object to send; must not be a string
+        @param timeout The timeout in seconds; if -1 use default.
+        """
+
+        if msg.xid == None:
+            msg.xid = ofutils.gen_xid( )
+
+        self.logger.debug( "Running transaction %d" % msg.xid )
+
+        with self.xid_cv:
+            if self.xid:
+                self.logger.error( "Can only run one transaction at a time" )
+                return (None, None)
+
+            self.xid = msg.xid
+            self.xid_response = None
+            self.message_send( msg )
+
+            self.logger.debug( "Waiting for transaction %d" % msg.xid )
+            ofutils.timed_wait( self.xid_cv, lambda: self.xid_response,
+                                timeout=timeout )
+
+            if self.xid_response:
+                (resp, pkt) = self.xid_response
+                self.xid_response = None
+            else:
+                (resp, pkt) = (None, None)
+
+        if resp is None:
+            self.logger.warning( "No response for xid " + str( self.xid ) )
+        return (resp, pkt)
+
+    def message_send( self, msg ):
+        """
+        Send the message to the switch
+
+        @param msg A string or OpenFlow message object to be forwarded to
+        the switch.
+        """
+        if not self.switch_socket:
+            # Sending a string indicates the message is ready to go
+            raise Exception( "no socket" )
+
+        if msg.xid == None:
+            msg.xid = ofutils.gen_xid( )
+
+        outpkt = msg.pack( )
+
+        self.logger.debug( "Msg out: version %d class %s len %d xid %d",
+                           msg.version, type( msg ).__name__, len( outpkt ),
+                           msg.xid )
+
+        with self.tx_lock:
+            if self.switch_socket.sendall( outpkt ) is not None:
+                raise AssertionError( "failed to send message to switch" )
+
+        return 0  # for backwards compatibility
+
+    def clear_queue( self ):
+        """
+        Clear the input queue and report the number of messages
+        that were in it
+        """
+        enqueued_pkt_count = len( self.packets )
+        with self.packets_cv:
+            self.packets = [ ]
+        return enqueued_pkt_count
+
+    def __str__( self ):
+        string = "Controller:\n"
+        string += "  state           " + self.dbg_state + "\n"
+        string += "  switch_addr     " + str( self.switch_addr ) + "\n"
+        string += "  pending pkts    " + str( len( self.packets ) ) + "\n"
+        string += "  total pkts      " + str( self.packets_total ) + "\n"
+        string += "  expired pkts    " + str( self.packets_expired ) + "\n"
+        string += "  handled pkts    " + str( self.packets_handled ) + "\n"
+        string += "  poll discards   " + str( self.poll_discards ) + "\n"
+        string += "  parse errors    " + str( self.parse_errors ) + "\n"
+        string += "  sock errrors    " + str( self.socket_errors ) + "\n"
+        string += "  max pkts        " + str( self.max_pkts ) + "\n"
+        string += "  target switch   " + str( self.switch ) + "\n"
+        string += "  host            " + str( self.host ) + "\n"
+        string += "  port            " + str( self.port ) + "\n"
+        string += "  keep_alive      " + str( self.keep_alive ) + "\n"
+        string += "  pkt_in_run      " + str( self.pkt_in_run ) + "\n"
+        string += "  pkt_in_dropped  " + str( self.pkt_in_dropped ) + "\n"
+        return string
+
+    def show( self ):
+        print str( self )
+
+
+def sample_handler( controller, msg, pkt ):
+    """
+    Sample message handler
+
+    This is the prototype for functions registered with the controller
+    class for packet reception
+
+    @param controller The controller calling the handler
+    @param msg The parsed message object
+    @param pkt The raw packet that was received on the socket.  This is
+    in case the packet contains extra unparsed data.
+    @returns Boolean value indicating if the packet was handled.  If
+    not handled, the packet is placed in the queue for pollers to received
+    """
+    pass
diff --git a/Fabric/Utilities/src/python/oftest/dataplane.py b/Fabric/Utilities/src/python/oftest/dataplane.py
new file mode 100644
index 0000000..df79d47
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/dataplane.py
@@ -0,0 +1,394 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+OpenFlow Test Framework
+
+DataPlane and DataPlanePort classes
+
+Provide the interface to the control the set of ports being used
+to stimulate the switch under test.
+
+See the class dataplaneport for more details.  This class wraps
+a set of those objects allowing general calls and parsing
+configuration.
+
+@todo Add "filters" for matching packets.  Actions supported
+for filters should include a callback or a counter
+"""
+
+import sys
+import os
+import socket
+import time
+import select
+import logging
+from threading import Thread
+from threading import Lock
+from threading import Condition
+import ofutils
+import netutils
+from pcap_writer import PcapWriter
+
+if "linux" in sys.platform:
+    import afpacket
+else:
+    import pcap
+
+def match_exp_pkt(self, exp_pkt, pkt):
+    """
+    Compare the string value of pkt with the string value of exp_pkt,
+    and return True iff they are identical.  If the length of exp_pkt is
+    less than the minimum Ethernet frame size (60 bytes), then padding
+    bytes in pkt are ignored.
+    """
+    e = str(exp_pkt)
+    p = str(pkt)
+    if len(e) < 60:
+        p = p[:len(e)]
+
+    #return e == p
+    #some nic card have capature problem, will have more bytes capatured.
+    if pkt.find(exp_pkt) >=0:
+        return True
+    else:
+        if self.config["dump_packet"]:
+            self.logger.debug("rx pkt    ->"+(" ".join("{:02x}".format(ord(c)) for c in pkt)))
+            self.logger.debug("expect pkt->"+(" ".join("{:02x}".format(ord(c)) for c in exp_pkt)))
+
+        return False
+
+
+class DataPlanePortLinux:
+    """
+    Uses raw sockets to capture and send packets on a network interface.
+    """
+
+    RCV_SIZE_DEFAULT = 4096
+    ETH_P_ALL = 0x03
+    RCV_TIMEOUT = 10000
+
+    def __init__(self, interface_name, port_number):
+        """
+        @param interface_name The name of the physical interface like eth1
+        """
+        self.interface_name = interface_name
+        self.socket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, 0)
+        afpacket.enable_auxdata(self.socket)
+        self.socket.bind((interface_name, self.ETH_P_ALL))
+        netutils.set_promisc(self.socket, interface_name)
+        self.socket.settimeout(self.RCV_TIMEOUT)
+
+    def __del__(self):
+        if self.socket:
+            self.socket.close()
+
+    def fileno(self):
+        """
+        Return an integer file descriptor that can be passed to select(2).
+        """
+        return self.socket.fileno()
+
+    def recv(self):
+        """
+        Receive a packet from this port.
+        @retval (packet data, timestamp)
+        """
+        pkt = afpacket.recv(self.socket, self.RCV_SIZE_DEFAULT)
+        return (pkt, time.time())
+
+    def send(self, packet):
+        """
+        Send a packet out this port.
+        @param packet The packet data to send to the port
+        @retval The number of bytes sent
+        """
+        return self.socket.send(packet)
+
+    def down(self):
+        """
+        Bring the physical link down.
+        """
+        #os.system("ifconfig down %s" % self.interface_name)
+        os.system("ifconfig %s down" % self.interface_name)
+
+    def up(self):
+        """
+        Bring the physical link up.
+        """
+        #os.system("ifconfig up %s" % self.interface_name)
+        os.system("ifconfig %s up" % self.interface_name)
+
+
+class DataPlanePortPcap:
+    """
+    Alternate port implementation using libpcap. This is used by non-Linux
+    operating systems.
+    """
+
+    def __init__(self, interface_name, port_number):
+        self.pcap = pcap.pcap(interface_name)
+        self.pcap.setnonblock()
+
+    def fileno(self):
+        return self.pcap.fileno()
+
+    def recv(self):
+        (timestamp, pkt) = next(self.pcap)
+        return (pkt[:], timestamp)
+
+    def send(self, packet):
+        if hasattr(self.pcap, "inject"):
+            return self.pcap.inject(packet, len(packet))
+        else:
+           return self.pcap.sendpacket(packet)
+
+    def down(self):
+        pass
+
+    def up(self):
+        pass
+
+class DataPlane(Thread):
+    """
+    This class provides methods to send and receive packets on the dataplane.
+    It uses the DataPlanePort class, or an alternative implementation of that
+    interface, to do IO on a particular port. A background thread is used to
+    read packets from the dataplane ports and enqueue them to be read by the
+    test. The kill() method must be called to shutdown this thread.
+    """
+
+    MAX_QUEUE_LEN = 100
+
+    def __init__(self, config=None):
+        Thread.__init__(self)
+
+        # dict from port number to port object
+        self.ports = {}
+
+        # dict from port number to list of (timestamp, packet)
+        self.packet_queues = {}
+
+        # cvar serves double duty as a regular top level lock and
+        # as a condition variable
+        self.cvar = Condition()
+
+        # Used to wake up the event loop from another thread
+        self.waker = ofutils.EventDescriptor()
+        self.killed = False
+
+        self.logger = logging.getLogger("dataplane")
+        self.pcap_writer = None
+
+        if config is None:
+            self.config = {}
+        else:
+            self.config = config;
+
+        ############################################################
+        #
+        # The platform/config can provide a custom DataPlanePort class
+        # here if you have a custom implementation with different
+        # behavior.
+        #
+        # Set config.dataplane.portclass = MyDataPlanePortClass
+        # where MyDataPlanePortClass has the same interface as the class
+        # DataPlanePort defined here.
+        #
+        if "dataplane" in self.config and "portclass" in self.config["dataplane"]:
+            self.dppclass = self.config["dataplane"]["portclass"]
+        elif "linux" in sys.platform:
+            self.dppclass = DataPlanePortLinux
+        else:
+            self.dppclass = DataPlanePortPcap
+
+        self.start()
+
+    def run(self):
+        """
+        Activity function for class
+        """
+        while not self.killed:
+            sockets = [self.waker] + self.ports.values()
+            try:
+                sel_in, sel_out, sel_err = select.select(sockets, [], [], 1)
+            except:
+                print sys.exc_info()
+                self.logger.error("Select error, exiting")
+                break
+
+            with self.cvar:
+                for port in sel_in:
+                    if port == self.waker:
+                        self.waker.wait()
+                        continue
+                    else:
+                        # Enqueue packet
+                        pkt, timestamp = port.recv()
+                        port_number = port._port_number
+                        self.logger.debug("Pkt len %d in on port %d",
+                                          len(pkt), port_number)
+                        if self.pcap_writer:
+                            self.pcap_writer.write(pkt, timestamp, port_number)
+                        queue = self.packet_queues[port_number]
+                        if len(queue) >= self.MAX_QUEUE_LEN:
+                            # Queue full, throw away oldest
+                            queue.pop(0)
+                            self.logger.debug("Discarding oldest packet to make room")
+                        queue.append((pkt, timestamp))
+                self.cvar.notify_all()
+
+        self.logger.info("Thread exit")
+
+    def port_add(self, interface_name, port_number):
+        """
+        Add a port to the dataplane
+        @param interface_name The name of the physical interface like eth1
+        @param port_number The port number used to refer to the port
+        Stashes the port number on the created port object.
+        """
+        self.ports[port_number] = self.dppclass(interface_name, port_number)
+        self.ports[port_number]._port_number = port_number
+        self.packet_queues[port_number] = []
+        # Need to wake up event loop to change the sockets being selected on.
+        self.waker.notify()
+
+    def send(self, port_number, packet):
+        """
+        Send a packet to the given port
+        @param port_number The port to send the data to
+        @param packet Raw packet data to send to port
+        """
+        self.logger.debug("Sending %d bytes to port %d" %
+                          (len(packet), port_number))
+        if self.pcap_writer:
+            self.pcap_writer.write(packet, time.time(), port_number)
+        bytes = self.ports[port_number].send(packet)
+        if bytes != len(packet):
+            self.logger.error("Unhandled send error, length mismatch %d != %d" %
+                     (bytes, len(packet)))
+        return bytes
+
+    def oldest_port_number(self):
+        """
+        Returns the port number with the oldest packet, or
+        None if no packets are queued.
+        """
+        min_port_number = None
+        min_time = float('inf')
+        for (port_number, queue) in self.packet_queues.items():
+            if queue and queue[0][1] < min_time:
+                min_time = queue[0][1]
+                min_port_number = port_number
+        return min_port_number
+
+    # Dequeues and yields packets in the order they were received.
+    # Yields (port number, packet, received time).
+    # If port_number is not specified yields packets from all ports.
+    def packets(self, port_number=None):
+        while True:
+            rcv_port_number = port_number or self.oldest_port_number()
+
+            if rcv_port_number == None:
+                self.logger.debug("Out of packets on all ports")
+                break
+
+            queue = self.packet_queues[rcv_port_number]
+
+            if len(queue) == 0:
+                self.logger.debug("Out of packets on port %d", rcv_port_number)
+                break
+
+            pkt, time = queue.pop(0)
+            yield (rcv_port_number, pkt, time)
+
+    def poll(self, port_number=None, timeout=-1, exp_pkt=None):
+        """
+        Poll one or all dataplane ports for a packet
+
+        If port_number is given, get the oldest packet from that port.
+        Otherwise, find the port with the oldest packet and return
+        that packet.
+
+        If exp_pkt is true, discard all packets until that one is found
+
+        @param port_number If set, get packet from this port
+        @param timeout If positive and no packet is available, block
+        until a packet is received or for this many seconds
+        @param exp_pkt If not None, look for this packet and ignore any
+        others received.  Note that if port_number is None, all packets
+        from all ports will be discarded until the exp_pkt is found
+        @return The triple port_number, packet, pkt_time where packet
+        is received from port_number at time pkt_time.  If a timeout
+        occurs, return None, None, None
+        """
+
+        if exp_pkt and not port_number:
+            self.logger.warn("Dataplane poll with exp_pkt but no port number")
+
+        # Retrieve the packet. Returns (port number, packet, time).
+        def grab():
+            self.logger.debug("Grabbing packet")
+            for (rcv_port_number, pkt, time) in self.packets(port_number):
+                self.logger.debug("Checking packet from port %d", rcv_port_number)
+                if not exp_pkt or match_exp_pkt(self, exp_pkt, pkt):
+                    return (rcv_port_number, pkt, time)
+            self.logger.debug("Did not find packet")
+            return None
+
+        with self.cvar:
+            ret = ofutils.timed_wait(self.cvar, grab, timeout=timeout)
+
+        if ret != None:
+            return ret
+        else:
+            self.logger.debug("Poll time out, no packet from " + str(port_number))
+            return (None, None, None)
+
+    def kill(self):
+        """
+        Stop the dataplane thread.
+        """
+        self.killed = True
+        self.waker.notify()
+        self.join()
+        # Explicitly release ports to ensure we don't run out of sockets
+        # even if someone keeps holding a reference to the dataplane.
+        del self.ports
+
+    def port_down(self, port_number):
+        """Brings the specified port down"""
+        self.ports[port_number].down()
+
+    def port_up(self, port_number):
+        """Brings the specified port up"""
+        self.ports[port_number].up()
+
+    def flush(self):
+        """
+        Drop any queued packets.
+        """
+        for port_number in self.packet_queues.keys():
+            self.packet_queues[port_number] = []
+
+    def start_pcap(self, filename):
+        assert(self.pcap_writer == None)
+        self.pcap_writer = PcapWriter(filename)
+
+    def stop_pcap(self):
+        if self.pcap_writer:
+            self.pcap_writer.close()
+            self.pcap_writer = None
diff --git a/Fabric/Utilities/src/python/oftest/generators.py b/Fabric/Utilities/src/python/oftest/generators.py
new file mode 100644
index 0000000..74d2ccc
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/generators.py
@@ -0,0 +1,95 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+from oftest.testutils import *
+from oftest import config
+import oftest.base_tests as base_tests
+import time
+
+class QinQPacketGenerator( base_tests.DataPlaneOnly ):
+    """
+    Generator for QinQ packets.
+    """
+    def runTest( self ):
+        # Get the ports and the interfaces
+        ports           = config[ "interfaces" ]
+        in_port         = ports[0][0]
+        in_interface    = ports[0][1].strip()
+        out_port        = ports[1][0]
+        out_interface   = ports[1][1].strip()
+        outer_vlan      = 20
+        innner_vlan     = 10
+        # Generating the packets
+        parsed_pkt = simple_tcp_packet_two_vlan(
+            pktlen=108,
+            out_dl_vlan_enable=True,
+            out_vlan_vid=outer_vlan,
+            in_dl_vlan_enable=True,
+            in_vlan_vid=innner_vlan
+            )
+        qinq_pkt = str( parsed_pkt )
+        # Sending the packet
+        print "\nSending packet on", out_interface
+        while True :
+            self.dataplane.send( in_port, qinq_pkt )
+            time.sleep(1)
+
+class VlanPacketGenerator( base_tests.DataPlaneOnly ):
+    """
+    Generator for vlan packets.
+    """
+    def runTest( self ):
+        # Get the ports and the interfaces
+        ports           = config[ "interfaces" ]
+        in_port         = ports[0][0]
+        in_interface    = ports[0][1].strip()
+        out_port        = ports[1][0]
+        out_interface   = ports[1][1].strip()
+        outer_vlan      = 20
+        # Generating the packets
+        parsed_pkt = simple_tcp_packet(
+            pktlen=108,
+            dl_vlan_enable=True,
+            vlan_vid=outer_vlan
+            )
+        vlan_pkt = str( parsed_pkt )
+        # Sending the packet
+        print "\nSending packet on", out_interface
+        while True :
+            self.dataplane.send( in_port, vlan_pkt )
+            time.sleep(1)
+
+class UntaggedPacketGenerator( base_tests.DataPlaneOnly ):
+    """
+    Generator for untagged packets.
+    """
+    def runTest( self ):
+        # Get the ports and the interfaces
+        ports           = config[ "interfaces" ]
+        in_port         = ports[0][0]
+        in_interface    = ports[0][1].strip()
+        out_port        = ports[1][0]
+        out_interface   = ports[1][1].strip()
+        # Generating the packets
+        parsed_pkt = simple_tcp_packet(
+            pktlen=108,
+            )
+        untagged_pkt = str( parsed_pkt )
+        # Sending the packet
+        print "\nSending packet on", out_interface
+        while True :
+            self.dataplane.send( in_port, untagged_pkt )
+            time.sleep(1)
diff --git a/Fabric/Utilities/src/python/oftest/help_formatter.py b/Fabric/Utilities/src/python/oftest/help_formatter.py
new file mode 100644
index 0000000..f877374
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/help_formatter.py
@@ -0,0 +1,26 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import optparse
+
+# Don't wrap description text to give us more control over newlines.
+class HelpFormatter(optparse.IndentedHelpFormatter):
+    def format_description(self, description):
+        if description:
+            indent = " "*self.current_indent
+            return indent + description
+        else:
+            return None
diff --git a/Fabric/Utilities/src/python/oftest/illegal_message.py b/Fabric/Utilities/src/python/oftest/illegal_message.py
new file mode 100644
index 0000000..94c9572
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/illegal_message.py
@@ -0,0 +1,59 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Support an illegal message
+"""
+
+import struct
+import ofp
+
+class illegal_message_type(object):
+    version = ofp.OFP_VERSION
+    type = 217
+
+    def __init__(self, xid=None):
+        self.xid = xid
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(buf):
+        raise NotImplementedError()
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.version != other.version: return False
+        if self.type != other.type: return False
+        if self.xid != other.xid: return False
+        return True
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def __str__(self):
+        return self.show()
+
+    def show(self):
+        return "illegal_message_type"
diff --git a/Fabric/Utilities/src/python/oftest/mpls.py b/Fabric/Utilities/src/python/oftest/mpls.py
new file mode 100644
index 0000000..2754e87
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/mpls.py
@@ -0,0 +1,40 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Imported from scapy at revision 1270:113ef25f9583
+# This file is not included in the Ubuntu packages of scapy, so it is checked
+# in to our repo to simplify installation. This file is under the GPLv2.
+
+# http://trac.secdev.org/scapy/ticket/31 
+
+# scapy.contrib.description = MPLS
+# scapy.contrib.status = loads
+
+from scapy.packet import Packet,bind_layers
+from scapy.fields import BitField,ByteField
+from scapy.layers.l2 import Ether
+
+class MPLS(Packet): 
+   name = "MPLS" 
+   fields_desc =  [ BitField("label", 3, 20), 
+                    BitField("cos", 0, 3), 
+                    BitField("s", 1, 1), 
+                    ByteField("ttl", 0)  ] 
+
+bind_layers(Ether, MPLS, type=0x8847)
+
+# Not in upstream scapy
+bind_layers(MPLS, MPLS, s=0)
diff --git a/Fabric/Utilities/src/python/oftest/netutils.py b/Fabric/Utilities/src/python/oftest/netutils.py
new file mode 100644
index 0000000..09a3835
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/netutils.py
@@ -0,0 +1,77 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+
+"""
+Network utilities for the OpenFlow test framework
+"""
+
+###########################################################################
+##                                                                         ##
+## Promiscuous mode enable/disable                                         ##
+##                                                                         ##
+## Based on code from Scapy by Phillippe Biondi                            ##
+##                                                                         ##
+##                                                                         ##
+## This program is free software; you can redistribute it and/or modify it ##
+## under the terms of the GNU General Public License as published by the   ##
+## Free Software Foundation; either version 2, or (at your option) any     ##
+## later version.                                                          ##
+##                                                                         ##
+## This program is distributed in the hope that it will be useful, but     ##
+## WITHOUT ANY WARRANTY; without even the implied warranty of              ##
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       ##
+## General Public License for more details.                                ##
+##                                                                         ##
+#############################################################################
+
+import socket
+from fcntl import ioctl
+import struct
+
+# From net/if_arp.h
+ARPHDR_ETHER = 1
+ARPHDR_LOOPBACK = 772
+
+# From bits/ioctls.h
+SIOCGIFHWADDR  = 0x8927          # Get hardware address
+SIOCGIFINDEX   = 0x8933          # name -> if_index mapping
+
+# From netpacket/packet.h
+PACKET_ADD_MEMBERSHIP  = 1
+PACKET_DROP_MEMBERSHIP = 2
+PACKET_MR_PROMISC      = 1
+
+# From bits/socket.h
+SOL_PACKET = 263
+
+def get_if(iff,cmd):
+  s=socket.socket()
+  ifreq = ioctl(s, cmd, struct.pack("16s16x",iff))
+  s.close()
+  return ifreq
+
+def get_if_index(iff):
+  return int(struct.unpack("I",get_if(iff, SIOCGIFINDEX)[16:20])[0])
+
+def set_promisc(s,iff,val=1):
+  mreq = struct.pack("IHH8s", get_if_index(iff), PACKET_MR_PROMISC, 0, "")
+  if val:
+      cmd = PACKET_ADD_MEMBERSHIP
+  else:
+      cmd = PACKET_DROP_MEMBERSHIP
+  s.setsockopt(SOL_PACKET, cmd, mreq)
+
diff --git a/Fabric/Utilities/src/python/oftest/ofdpa_utils.py b/Fabric/Utilities/src/python/oftest/ofdpa_utils.py
new file mode 100755
index 0000000..8c97b1f
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/ofdpa_utils.py
@@ -0,0 +1,184 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+
+A set of inter-test utility functions for dealing with OF-DPA
+
+
+"""
+
+import logging, subprocess, time
+import ofp
+
+from oftest import config
+from oftest.testutils import *
+
+def forceOfdpaRestart( user ):
+    output = 1;
+    credential = user;
+    test = subprocess.Popen(["ssh", credential, "service ofdpa restart &> /dev/null"]);
+    time.sleep(1);
+    while output < 10:
+        output = int(subprocess.check_output(["ssh", credential, "client_cfg_purge | wc -l"]));
+        time.sleep(1);
+    subprocess.Popen(["ssh", credential, "brcm-indigo-ofdpa-ofagent -t 10.128.0.220 &> /dev/null"], stdout=subprocess.PIPE);
+
+def forceOfdpaStop( user ):
+    subprocess.Popen(["ssh", user, "ps ax | grep 'brcm-indigo-ofdpa-ofagent' | awk '{print $1}' | xargs sudo kill"], stdout=subprocess.PIPE);
+
+
+class table(object):
+    """ Metadata on each OFDPA table """
+    def __init__(self, table_id, table_name):
+        self.table_id = table_id
+        self.table_name = table_name
+    # TODO consider adding type checking verification here
+
+INGRESS_TABLE           = table(0, "Ingress")
+VLAN_TABLE              = table(10, "VLAN")
+MACTERM_TABLE           = table(20, "MacTerm")
+UNICAST_ROUTING_TABLE   = table(30, "Unicast Routing")
+MULTICAST_ROUTING_TABLE = table(40, "Multicast Routing")
+BRIDGING_TABLE          = table(50, "Bridging Table")
+ACL_TABLE               = table(60, "ACL Policy Table")
+#.... FIXME add all tables
+
+DEFAULT_VLAN = 1
+
+def enableVlanOnPort(controller, vlan, port=ofp.OFPP_ALL, priority=0):
+    if port == ofp.OFPP_ALL:
+        ports = sorted(config["port_map"].keys())
+    else:
+        ports = [port]
+    for port in ports:
+        tagged_match = ofp.match([
+                ofp.oxm.in_port(port),
+                ofp.oxm.vlan_vid(vlan | ofp.OFPVID_PRESENT)
+                ])
+
+        request = ofp.message.flow_add(
+            table_id = VLAN_TABLE.table_id,
+            cookie = 0xdead,
+            match = tagged_match,
+            instructions = [
+                ofp.instruction.goto_table(MACTERM_TABLE.table_id),
+#                 ofp.instruction.apply_actions(
+#                     actions=[
+#                         ofp.action.push_vlan(ethertype=0x8100), # DO NOT PUT THIS FOR OF-DPA 2.0 EA1 - seems to not matter for EA2
+#                         ofp.action.set_field(ofp.oxm.vlan_vid( ofp.OFPVID_PRESENT | vlan))
+#                     ]),
+                    ],
+            buffer_id = ofp.OFP_NO_BUFFER,
+            priority = priority)
+
+        logging.info("Inserting vlan rule allowing tagged vlan %d on port %d" % (vlan, port))
+        controller.message_send(request)
+        do_barrier(controller)
+        verify_no_errors(controller)
+
+
+def installDefaultVlan(controller, vlan=DEFAULT_VLAN, port=ofp.OFPP_ALL, priority=0):
+    """ Insert a rule that maps all untagged traffic to vlan $vlan
+
+    In OFDPA, table 10 (the vlan table) requires that all traffic be
+    mapped to an internal vlan else the packets be dropped.  This function
+    sets up a default vlan mapping all untagged traffic to an internal VLAN.
+
+    With OF-DPA, before you can insert a 'untagged to X' rule on a
+    port, you must first insert a 'X --> X' rule for the same port.
+
+    Further, the 'X --> X' rule must set ofp.OFPVID_PRESENT even
+    though 'X' is non-zero.
+
+    The 'controller' variable is self.controller from a test
+    """
+    # OFDPA seems to be dumb and wants each port set individually
+    #       Can't set all ports by using OFPP_ALL
+    if port == ofp.OFPP_ALL:
+        ports = sorted(config["port_map"].keys())
+    else:
+        ports = [port]
+
+    for port in ports:
+        # enable this vlan on this port before we can map untagged packets to the vlan
+        enableVlanOnPort(controller, vlan, port)
+
+        untagged_match = ofp.match([
+                ofp.oxm.in_port(port),
+                # OFDPA 2.0 says untagged is vlan_id=0, mask=ofp.OFPVID_PRESENT
+                ofp.oxm.vlan_vid_masked(0,ofp.OFPVID_PRESENT)    # WTF OFDPA 2.0EA2 -- really!?
+                ])
+
+        request = ofp.message.flow_add(
+            table_id = VLAN_TABLE.table_id,
+            cookie = 0xbeef,
+            match = untagged_match,
+            instructions = [
+                ofp.instruction.apply_actions(
+                    actions=[
+                        #ofp.action.push_vlan(ethertype=0x8100),
+                        ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan))
+                    ]),
+                ofp.instruction.goto_table(MACTERM_TABLE.table_id)   
+                    ],
+            buffer_id = ofp.OFP_NO_BUFFER,
+            priority = priority)
+
+        logging.info("Inserting default vlan sending all untagged traffic to vlan %d on port %d" % (vlan, port))
+        controller.message_send(request)
+        do_barrier(controller)
+        verify_no_errors(controller)
+
+
+_group_types = {
+    "L2 Interface": 0,
+    "L2 Rewrite" : 1,
+    "L3 Unicast" : 2,
+    "L2 Multicast" : 3,
+    "L2 Flood" : 4,
+    "L3 Interface" : 5,
+    "L3 Multicast": 6,
+    "L3 ECMP": 7,
+    "L2 Data Center Overlay": 8,
+    "MPLS Label" : 9,
+    "MPLS Forwarding" :10,
+    "L2 Unfiltered Interface": 11,
+    "L2 Loopback": 12,
+}
+
+
+def makeGroupID(groupType, local_id):
+    """ Group IDs in OF-DPA have rich meaning
+
+    @param groupType is a key in _group_types
+    @param local_id is an integer 0<= local_id < 2**27,
+        but it may have more semantic meaning depending on the
+        groupType
+
+
+    Read Section 4.3 of the OF-DPA manual on groups for 
+    details
+    """
+    if groupType not in _group_types:
+        raise KeyError("%s not a valid OF-DPA group type" % groupType)
+    if local_id < 0 or local_id >=134217728:
+        raise ValueError("local_id %d must be  0<= local_id < 2**27" % local_id)
+    return (_group_types[groupType] << 28) + local_id
+
+
+def delete_all_recursive_groups(controller):
+    pass
diff --git a/Fabric/Utilities/src/python/oftest/oft12/__init__.py b/Fabric/Utilities/src/python/oftest/oft12/__init__.py
new file mode 100644
index 0000000..d4e8062
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/oft12/__init__.py
@@ -0,0 +1,16 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
diff --git a/Fabric/Utilities/src/python/oftest/oft12/packet.py b/Fabric/Utilities/src/python/oftest/oft12/packet.py
new file mode 100644
index 0000000..55724d6
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/oft12/packet.py
@@ -0,0 +1,1315 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+######################################################################
+#
+# All files associated with the OpenFlow Python Test (oftest) are
+# made available for public use and benefit with the expectation
+# that others will use, modify and enhance the Software and contribute
+# those enhancements back to the community. However, since we would
+# like to make the Software available for broadest use, with as few
+# restrictions as possible permission is hereby granted, free of
+# charge, to any person obtaining a copy of this Software to deal in
+# the Software under the copyrights without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject
+# to the following conditions:
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# 
+######################################################################
+import os
+
+"""
+OpenFlow packet class
+
+This class implements the basic abstraction of an OpenFlow packet.  It
+includes parsing functionality and OpenFlow actions related to 
+packet modifications.
+"""
+
+import socket
+import struct
+import logging
+import ofp
+import unittest
+import binascii
+import string
+import collections #@UnresolvedImport
+
+ETHERTYPE_IP = 0x0800
+ETHERTYPE_VLAN = 0x8100
+ETHERTYPE_VLAN_QinQ = 0x88a8
+ETHERTYPE_ARP = 0x0806
+ETHERTYPE_MPLS = 0x8847
+ETHERTYPE_MPLS_MCAST = 0x8848
+ETHERTYPES_MPLS = [ETHERTYPE_MPLS, ETHERTYPE_MPLS_MCAST]
+
+DL_MASK_ALL = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
+NW_MASK_ALL = 0xffffffff
+
+MPLS_BOTTOM_OF_STACK = 0x00000100
+
+# Sigh.. not python26
+#MplsTag = collections.namedtuple("MplsTag", "label tc ttl")
+
+class MplsTag(object):
+    def __init__(self, label, tc, ttl):
+        self.label = label
+        self.tc = tc
+        self.ttl = ttl
+    def pack(self, bos = 0):
+        packed_tag = ((self.label & 0xfffff) << 12) | \
+                     ((self.tc & 0x7) << 9) | \
+                     (self.ttl & 0xFF) | \
+                     (MPLS_BOTTOM_OF_STACK if bos else 0)
+        return packed_tag
+    
+    def unpack(packed_tag):
+        tag = MplsTag(packed_tag >> 12,
+                      (packed_tag >> 9) & 0x0007,
+                      packed_tag & 0xFF)
+        bos = bool(packed_tag & MPLS_BOTTOM_OF_STACK)
+        return (tag, bos)
+    unpack = staticmethod(unpack)
+
+class Packet(object):
+    """
+    Packet abstraction
+
+    This is meant to support the abstraction of a packet in an
+    OpenFlow 1.1 switch so it includes an action set, ingress port,
+    and metadata.  These members may be ignored and the rest of the
+    packet parsing and modification functions used to manipulate
+    a packet.
+    """
+    
+    icmp_counter = 1
+
+    def __init__(self, in_port=None, data=""):
+        # Use entries in match when possible.
+        self.in_port = in_port
+        self.data = data
+        self.bytes = len(data)
+        self.match = ofp.ofp_match()
+        self.logger = logging.getLogger("packet")  
+        self.instructions = []
+        # parsable tags
+        self.ip_header_offset = None
+        self.tcp_header_offset = None
+        self.mpls_tag_offset = None         # pointer to outer mpls tag
+        self.vlan_tag_offset = None         # pointer to outer vlan tag
+        self.action_set = {}
+        self.queue_id = 0
+
+        if self.data != "":
+            self.parse()
+
+    def show(self):
+        """ Return a ascii hex representation of the packet's data"""
+        ret = ""
+        c = 0
+        for b in list(self.data):
+            if c != 0:
+                if c % 16  == 0:
+                    ret += '\n'
+                elif c % 8 == 0:
+                    ret += '  '
+            c += 1
+            ret += "%0.2x " % struct.unpack('B', b)
+        return ret
+
+    def __repr__(self):
+        return self.data
+    
+    def __str__(self):
+        return  self.__repr__()
+
+    def __len__(self):
+        return len(self.data)
+
+    def simple_tcp_packet(self,
+                          pktlen=100, 
+                          dl_dst='00:01:02:03:04:05',
+                          dl_src='00:06:07:08:09:0a',
+                          dl_vlan_enable=False,
+                          dl_vlan_type=ETHERTYPE_VLAN,
+                          dl_vlan=0,
+                          dl_vlan_pcp=0,
+                          dl_vlan_cfi=0,
+                          mpls_type=None,
+                          mpls_tags=None,
+                          ip_src='192.168.0.1',
+                          ip_dst='192.168.0.2',
+                          ip_tos=0,
+                          ip_ttl=64,
+                          tcp_sport=1234,
+                          tcp_dport=80):
+        """
+        Return a simple dataplane TCP packet
+
+        Supports a few parameters:
+        @param len Length of packet in bytes w/o CRC
+        @param dl_dst Destinatino MAC
+        @param dl_src Source MAC
+        @param dl_vlan_enable True if the packet is with vlan, False otherwise
+        @param dl_vlan_type Ether type for VLAN
+        @param dl_vlan VLAN ID
+        @param dl_vlan_pcp VLAN priority
+        @param ip_src IP source
+        @param ip_dst IP destination
+        @param ip_tos IP ToS
+        @param tcp_dport TCP destination port
+        @param tcp_sport TCP source port
+
+        Generates a simple TCP request.  Users shouldn't assume anything 
+        about this packet other than that it is a valid ethernet/IP/TCP frame.
+        """
+        self.data = ""
+        self._make_ip_packet(dl_dst, dl_src, dl_vlan_enable, dl_vlan_type, 
+                             dl_vlan, dl_vlan_pcp, dl_vlan_cfi, 
+                             mpls_type, mpls_tags, 
+                             ip_tos, ip_ttl, ip_src, ip_dst, socket.IPPROTO_TCP)
+
+        # Add TCP header
+        self.data += struct.pack("!HHLLBBHHH",
+                                 tcp_sport,
+                                 tcp_dport,
+                                 1,     # tcp.seq
+                                 0,     # tcp.ack
+                                 0x50,  # tcp.doff + tcp.res1
+                                 0x12,  # tcp.syn + tcp.ack
+                                 0,     # tcp.wnd
+                                 0,     # tcp.check
+                                 0,     # tcp.urgent pointer
+                                 )
+
+        # Fill out packet
+        self.data += "D" * (pktlen - len(self.data))
+        return self
+    
+    def simple_icmp_packet(self,
+                          pktlen=100, 
+                          dl_dst='00:01:02:03:04:05',
+                          dl_src='00:06:07:08:09:0a',
+                          dl_vlan_enable=False,
+                          dl_vlan_type=ETHERTYPE_VLAN,
+                          dl_vlan=0,
+                          dl_vlan_pcp=0,
+                          dl_vlan_cfi=0,
+                          mpls_type=None,
+                          mpls_tags=None,
+                          ip_src='192.168.0.1',
+                          ip_dst='192.168.0.2',
+                          ip_tos=0,
+                          ip_ttl=64,
+                          icmp_type=8, # ICMP_ECHO_REQUEST
+                          icmp_code=0, 
+                          ):
+        """
+        Return a simple dataplane ICMP packet
+
+        Supports a few parameters:
+        @param len Length of packet in bytes w/o CRC
+        @param dl_dst Destinatino MAC
+        @param dl_src Source MAC
+        @param dl_vlan_enable True if the packet is with vlan, False otherwise
+        @param dl_vlan_type Ether type for VLAN
+        @param dl_vlan VLAN ID
+        @param dl_vlan_pcp VLAN priority
+        @param ip_src IP source
+        @param ip_dst IP destination
+        @param ip_tos IP ToS
+        @param tcp_dport TCP destination port
+        @param ip_sport TCP source port
+
+        Generates a simple TCP request.  Users shouldn't assume anything 
+        about this packet other than that it is a valid ethernet/IP/TCP frame.
+        """
+        self.data = ""
+        self._make_ip_packet(dl_dst, dl_src, dl_vlan_enable, dl_vlan_type, 
+                             dl_vlan, dl_vlan_pcp, dl_vlan_cfi, 
+                             mpls_type, mpls_tags,
+                             ip_tos,
+                              ip_ttl, ip_src, ip_dst, socket.IPPROTO_ICMP)
+
+        # Add ICMP header
+        self.data += struct.pack("!BBHHH",
+                                 icmp_type,
+                                 icmp_code,
+                                 0,  # icmp.checksum
+                                 os.getpid() & 0xffff,  # icmp.echo.id
+                                 Packet.icmp_counter   # icmp.echo.seq
+                                 )                  
+        Packet.icmp_counter += 1       
+
+        # Fill out packet
+        self.data += "D" * (pktlen - len(self.data))
+
+        return self
+
+    def _make_ip_packet(self, dl_dst, dl_src, dl_vlan_enable, dl_vlan_type, 
+                          dl_vlan, dl_vlan_pcp, dl_vlan_cfi, mpls_type, mpls_tags,
+                          ip_tos, ip_ttl, ip_src, ip_dst, ip_proto):
+        self.data = ""
+        addr = dl_dst.split(":")
+        for byte in map(lambda z: int(z, 16), addr):
+            self.data += struct.pack("!B", byte)
+        addr = dl_src.split(":")
+        for byte in map(lambda z: int(z, 16), addr):
+            self.data += struct.pack("!B", byte)
+
+        if (dl_vlan_enable):
+            # Form and add VLAN tag
+            self.data += struct.pack("!H", dl_vlan_type)
+            vtag = (dl_vlan & 0x0fff) | \
+                            (dl_vlan_pcp & 0x7) << 13 | \
+                            (dl_vlan_cfi & 0x1) << 12
+            self.data += struct.pack("!H", vtag)
+            
+        if mpls_tags:
+            # Add type/len field
+            self.data += struct.pack("!H", mpls_type)
+            mpls_tags = list(mpls_tags)          
+            while len(mpls_tags):
+                tag = mpls_tags.pop(0)
+                packed_tag = tag.pack(bos = not len(mpls_tags))
+                self.data += struct.pack("!I", packed_tag)
+            
+        else:
+            # Add type/len field
+            self.data += struct.pack("!H", ETHERTYPE_IP)
+
+        # Add IP header
+        v_and_hlen = 0x45  # assumes no ip or tcp options
+        ip_len = 120 + 40  # assumes no ip or tcp options
+        self.data += struct.pack("!BBHHHBBH", v_and_hlen, ip_tos, ip_len, 
+                                 0, # ip.id 
+                                 0, # ip.frag_off
+                                 ip_ttl, # ip.ttl
+                                 ip_proto,
+                                 0)  # ip.checksum
+        # convert  ipsrc/dst to ints
+        self.data += struct.pack("!LL", ascii_ip_to_bin(ip_src), 
+                                 ascii_ip_to_bin(ip_dst))
+
+    def length(self):
+        return len(self.data)
+
+    def clear_actions(self):
+        self.action_set = {}
+
+    def parse(self):
+        """
+        Update the headers in self.match based on self.data 
+        
+        Parses the relevant header features out of the packet, using
+        the table outlined in the OF1.1 spec, Figure 4
+        """
+        self.bytes = len(self.data)
+        self.match.in_port = self.in_port
+        self.match.type = ofp.OFPMT_STANDARD
+        self.match.length = ofp.OFPMT_STANDARD_LENGTH
+        self.match.wildcards = 0
+        self.match.nw_dst_mask = 0
+        self.match.nw_dst_mask = 0
+        self.match.dl_dst_mask = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
+        self.match.dl_src_mask = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
+        self.mpls_tag_offset = None
+        self.ip_header_offset = None
+        
+        idx = 0
+        try:
+            idx = self._parse_l2(idx)
+            
+            if self.match.dl_type == ETHERTYPE_IP:
+                self.ip_header_offset = idx 
+                idx = self._parse_ip(idx)
+                if self.match.nw_proto in [ socket.IPPROTO_TCP,
+                                            socket.IPPROTO_UDP,
+                                            socket.IPPROTO_ICMP]:
+                    self.tcp_header_offset = idx
+                    if self.match.nw_proto != socket.IPPROTO_ICMP:
+                        idx = self._parse_l4(idx)
+                    else:
+                        idx = self._parse_icmp(idx)
+            elif self.match.dl_type == ETHERTYPE_ARP:
+                self._parse_arp(idx)
+        except (parse_error), e:
+            self.logger.warn("Giving up on parsing packet, got %s" % 
+                             (str(e)))
+            return None
+        return self.match
+
+    def _parse_arp(self, idx):
+        # @todo Implement
+        pass
+
+    def _parse_l2(self, idx):
+        """
+        Parse Layer2 Headers of packet
+        
+        Parse ether src,dst,type (and vlan and QinQ headers if exists) from 
+        self.data starting at idx
+        """
+        if self.bytes < 14 :
+            raise parse_error("_parse_l2:: packet too shorter <14 bytes")
+            
+        self.match.dl_dst = list(struct.unpack("!6B", self.data[idx:idx+6]))
+        self.match.dl_dst_mask = DL_MASK_ALL
+        idx += 6
+        self.match.dl_src = list(struct.unpack("!6B", self.data[idx:idx+6]))
+        self.match.dl_src_mask = DL_MASK_ALL
+        idx += 6
+        #pdb.set_trace()
+        l2_type = struct.unpack("!H", self.data[idx:idx+2])[0]
+        idx += 2
+        if l2_type in [ETHERTYPE_VLAN, ETHERTYPE_VLAN_QinQ] :
+            self.vlan_tag_offset = 12
+            blob = struct.unpack("!H", self.data[idx:idx+2])[0]
+            idx += 2
+            self.match.dl_vlan_pcp = (blob & 0xe000) >> 13
+            #cfi = blob & 0x1000     #@todo figure out what to do if cfi!=0
+            self.match.dl_vlan = blob & 0x0fff
+            l2_type = struct.unpack("!H", self.data[idx:idx+2])[0]
+            # now skip past any more nest VLAN tags (per the spec)
+            while l2_type in [ETHERTYPE_VLAN, ETHERTYPE_VLAN_QinQ] :
+                idx += 4
+                if self.bytes < idx :
+                    raise parse_error("_parse_l2(): Too many vlan tags")
+                l2_type = struct.unpack("!H", self.data[idx:idx+2])[0]
+            idx += 2
+        else:
+            self.vlan_tag_offset = None
+            self.match.dl_vlan = ofp.OFPVID_NONE
+            self.match.dl_vlan_pcp = 0
+            
+        if l2_type in ETHERTYPES_MPLS:
+            if self.bytes < (idx + 4):
+                raise parse_error("_parse_l2:  Invalid MPLS header")
+            self.mpls_tag_offset = idx
+            tag = struct.unpack("!I", self.data[idx:idx+4])[0]
+            self.match.mpls_label = tag >> 12
+            self.match.mpls_tc = (tag >> 9) & 0x0007
+            idx += 4
+        else:
+            self.match.mpls_label = 0
+            self.match.mpls_tc = 0
+            
+        self.match.dl_type = l2_type
+        return idx
+            
+    def _parse_ip(self, idx):
+        """
+        Parse IP Headers of a packet starting at self.data[idx]
+        """
+        if self.bytes < (idx + 20) :
+            raise parse_error("_parse_ip: Invalid IP header")
+        # the three blanks are id (2bytes), frag offset (2bytes), 
+        # and ttl (1byte)
+        (hlen_and_v, self.match.nw_tos, len, _,_,_, self.match.nw_proto) = \
+            struct.unpack("!BBHHHBB", self.data[idx:idx+10])
+        #@todo add fragmentation parsing
+        hlen = hlen_and_v & 0x0f
+        (self.match.nw_src, self.match.nw_dst) = \
+            struct.unpack("!II", self.data[idx + 12:idx+20])
+        self.match.nw_dst_mask = NW_MASK_ALL
+        self.match.nw_src_mask = NW_MASK_ALL
+        return idx + (hlen *4) # this should correctly skip IP options
+    
+    def _parse_l4(self, idx):
+        """
+        Parse the src/dst ports of UDP and TCP packets
+        """
+        if self.bytes < (idx + 8):
+            raise parse_error("_parse_l4: Invalid L4 header")
+        (self.match.tp_src, self.match.tp_dst) = \
+            struct.unpack("!HH", self.data[idx:idx+4])
+
+    def _parse_icmp(self, idx):
+        """
+        Parse the type/code of ICMP Packets 
+        """
+        if self.bytes < (idx + 4):
+            raise parse_error("_parse_icmp: Invalid icmp header")
+        # yes, type and code get stored into tp_dst and tp_src...
+        (self.match.tp_src, self.match.tp_dst) = \
+            struct.unpack("!BB", self.data[idx:idx+2])
+
+
+    #
+    # NOTE:  See comment string in write_action regarding exactly
+    # when actions are executed (for apply vs write instructions)
+    #
+
+    def write_action(self, action):
+        """
+        Write the action into the packet's action set
+
+        Note that we do nothing to the packet when the write_action
+        instruction is executed.  We only record the actions for 
+        later processing.  Because of this, the output port is not
+        explicitly recorded in the packet; that state is recorded
+        in the action_set[set_output] item.
+        """
+        self.action_set[action.__class__] = action
+
+    def _set_1bytes(self,offset,byte):
+        """ Writes the byte at data[offset] 
+        
+        This function only exists to match the other _set_Xbytes() and
+        is trivial
+    
+        """
+        tmp= "%s%s" % (self.data[0:offset], 
+                               struct.pack('B',byte & 0xff))
+        if len(self.data) > offset + 1 :
+            tmp += self.data[offset+1:len(self.data)]
+        self.data=tmp
+
+    def _set_2bytes(self,offset,short):
+        """ Writes the 2 byte short in network byte order at data[offset] """
+        tmp= "%s%s" % (self.data[0:offset], 
+                               struct.pack('!H',short & 0xffff))
+        if len(self.data) > offset + 2 :
+            tmp += self.data[offset+2:len(self.data)]
+        self.data=tmp
+
+    def _set_4bytes(self,offset,word,forceNBO=True):
+        """ Writes the 4 byte word at data[offset] 
+        
+        Use network byte order if forceNBO is True,
+        else it's assumed that word is already in NBO
+        
+        """
+        # @todo Verify byte order
+        #pdb.set_trace()
+        fmt ="L"
+        if forceNBO:
+            fmt = '!' + fmt 
+        
+        tmp= "%s%s" % (self.data[0:offset], 
+                               struct.pack(fmt,word & 0xffffffff))
+        if len(self.data) > offset + 4 :
+            tmp += self.data[offset+4:len(self.data)]
+        self.data=tmp
+        
+    def _set_6bytes(self,offset,byte_list):
+        """ Writes the 6 byte sequence in the given order to data[offset] """
+        # @todo Do as a slice
+        tmp= self.data[0:offset] 
+        tmp += struct.pack("BBBBBB", *byte_list)
+        if len(self.data) > offset + 6 :
+            tmp += self.data[offset+6:len(self.data)]
+        self.data=tmp
+    
+    def _update_l4_checksum(self):
+        """ Recalculate the L4 checksum, if there
+        
+        Can be safely called on non-tcp/non-udp packets as a NOOP
+        """
+        if (self.ip_header_offset is None or 
+            self.tcp_header_offset is None):
+            return
+        if self.match.nw_proto == socket.IPPROTO_TCP:
+            return self._update_tcp_checksum()
+        elif self.match.nw_proto == socket.IPPROTO_UDP:
+            return self._update_udp_checksum()
+        
+    def _update_tcp_checksum(self):
+        """ Recalculate the TCP checksum
+        
+        @warning:  Must only be called on actual TCP Packets
+        """
+        #@todo implemnt tcp checksum update
+        pass
+    
+    def _update_udp_checksum(self):
+        """ Recalculate the TCP checksum
+        
+        @warning:  Must only be called on actual TCP Packets
+        """
+        #@todo implemnt udp checksum update
+        pass
+
+    def set_metadata(self, value, mask):
+        self.match.metadata = (self.match.metadata & ~mask) | \
+            (value & mask)
+
+    #
+    # These are the main action operations that take the 
+    # required parameters
+    # 
+    # Note that 'group', 'experimenter' and 'set_output' are only 
+    # implemented for the action versions.
+
+    def set_queue(self, queue_id):
+        self.queue_id = queue_id
+
+    def set_vlan_vid(self, vid):
+        # @todo Verify proper location of VLAN id
+        if self.vlan_tag_offset is None:
+            self.logger.debug("set_vlan_vid(): Adding new vlan tag to untagged packet")
+            self.push_vlan(ETHERTYPE_VLAN)
+        offset = self.vlan_tag_offset + 2
+        short = struct.unpack('!H', self.data[offset:offset+2])[0]
+        short = (short & 0xf000) | ((vid & 0x0fff) )
+        self.data = self.data[0:offset] + struct.pack('!H',short) + \
+                self.data[offset+2:len(self.data)]
+        self.match.dl_vlan = vid & 0x0fff
+        self.logger.debug("set_vlan_vid(): setting packet vlan_vid to 0x%x " % 
+                          self.match.dl_vlan)
+
+    def set_vlan_pcp(self, pcp):
+        # @todo Verify proper location of VLAN pcp
+        if self.vlan_tag_offset is None:
+            return
+        offset = self.vlan_tag_offset + 2
+        short = struct.unpack('!H', self.data[offset:offset+2])[0]
+        short = (pcp<<13 & 0xf000) | ((short & 0x0fff) )
+        self.data = self.data[0:offset] + struct.pack('!H',short) + \
+                self.data[offset+2:len(self.data)]
+        self.match.dl_vlan_pcp = pcp & 0xf
+
+    def set_dl_src(self, dl_src):
+        self._set_6bytes(6, dl_src)
+        self.match.dl_src = dl_src
+
+    def set_dl_dst(self, dl_dst):
+        self._set_6bytes(0, dl_dst)
+        self.match.dl_dst = dl_dst
+        
+    def set_nw_src(self, nw_src):
+        if self.ip_header_offset is None:
+            return
+        self._set_4bytes(self.ip_header_offset + 12, nw_src)
+        self._update_l4_checksum()
+        self.match.nw_src = nw_src
+    
+    def set_nw_dst(self, nw_dst):
+        # @todo Verify byte order
+        if self.ip_header_offset is None:
+            return
+        self._set_4bytes(self.ip_header_offset + 16, nw_dst)
+        self._update_l4_checksum()
+        self.match.nw_dst = nw_dst
+
+    def set_nw_tos(self, tos):
+        if self.ip_header_offset is None:
+            return
+        self._set_1bytes(self.ip_header_offset + 1, tos)
+        self.match.nw_tos = tos
+
+    def set_nw_ecn(self, ecn):
+        #@todo look up ecn implementation details
+        pass
+
+    def set_tp_src(self, tp_src):
+        if self.tcp_header_offset is None:
+            return
+        if (self.match.nw_proto == socket.IPPROTO_TCP or
+            self.match.nw_proto == socket.IPPROTO_UDP): 
+            self._set_2bytes(self.tcp_header_offset, tp_src)
+        elif (self.match.nw_proto == socket.IPPROTO_ICMP):
+            self._set_1bytes(self.tcp_header_offset, tp_src)
+        self._update_l4_checksum()
+        self.match.tp_src = tp_src
+            
+    def set_tp_dst(self, tp_dst):
+        if self.tcp_header_offset is None:
+            return
+        if (self.match.nw_proto == socket.IPPROTO_TCP or
+            self.match.nw_proto == socket.IPPROTO_UDP): 
+            self._set_2bytes(self.tcp_header_offset +2, tp_dst)
+        elif (self.match.nw_proto == socket.IPPROTO_ICMP):
+            self._set_1bytes(self.tcp_header_offset + 1, tp_dst)
+        self._update_l4_checksum()
+        self.match.tp_dst = tp_dst
+
+    IP_OFFSET_TTL = 8
+    
+    def copy_ttl_out(self):
+        if self.mpls_tag_offset is None:
+            # No MPLS tag.
+            return
+        outerTag = struct.unpack("!I", self.data[self.mpls_tag_offset:
+                                                 self.mpls_tag_offset+4])[0]
+        if not (outerTag & MPLS_BOTTOM_OF_STACK):
+            # Payload is another MPLS tag:
+            innerTag = struct.unpack("!I", self.data[self.mpls_tag_offset+4:
+                                                     self.mpls_tag_offset+8])[0]
+            outerTag = (outerTag & 0xFFFFFF00) | (innerTag & 0x000000FF)
+            self._set_4bytes(self.mpls_tag_offset, outerTag)
+        else:
+            # This MPLS tag is the bottom of the stack.
+            # See if the payload looks like it might be IPv4.
+            versionLen = struct.unpack("B", 
+                                       self.data[self.mpls_tag_offset+4])[0]
+            if versionLen >> 4 != 4:
+                # This is not IPv4.
+                return;
+            # This looks like IPv4, so copy the TTL.
+            ipTTL = struct.unpack("B", self.data[self.mpls_tag_offset + 4 +
+                                                 Packet.IP_OFFSET_TTL])[0]
+            outerTag = (outerTag & 0xFFFFFF00) | (ipTTL & 0xFF)
+            self._set_4bytes(self.mpls_tag_offset, outerTag)      
+            return
+
+    def copy_ttl_in(self):
+        if self.mpls_tag_offset is None:
+            # No MPLS tag.
+            return
+        outerTag = struct.unpack("!I", self.data[self.mpls_tag_offset:
+                                                 self.mpls_tag_offset+4])[0]
+        if not (outerTag & MPLS_BOTTOM_OF_STACK):
+            # Payload is another MPLS tag:
+            innerTag = struct.unpack("!I", self.data[self.mpls_tag_offset+4:
+                                                     self.mpls_tag_offset+8])[0]
+            innerTag = (innerTag & 0xFFFFFF00) | (outerTag & 0x000000FF)
+            self._set_4bytes(self.mpls_tag_offset+4, innerTag)
+        else:
+            # This MPLS tag is the bottom of the stack.
+            # See if the payload looks like it might be IPv4.
+            versionLen = struct.unpack("B", self.data[self.mpls_tag_offset+4])[0]
+            if versionLen >> 4 != 4:
+                # This is not IPv4.
+                return;
+            # This looks like IPv4, so copy the TTL.
+            self._set_1bytes(self.mpls_tag_offset + 4 + Packet.IP_OFFSET_TTL,
+                             outerTag & 0x000000FF) 
+            #@todo update checksum
+            return
+
+    def set_mpls_label(self, mpls_label):
+        if self.mpls_tag_offset is None:
+            return
+        tag = struct.unpack("!I", self.data[self.mpls_tag_offset:
+                                            self.mpls_tag_offset+4])[0]
+        tag = ((mpls_label & 0xfffff) << 12) | (tag & 0x00000fff)
+        self.match.mpls_label = mpls_label
+        self._set_4bytes(self.mpls_tag_offset, tag)
+
+    def set_mpls_tc(self, mpls_tc):
+        if self.mpls_tag_offset is None:
+            return
+        tag = struct.unpack("!I", self.data[self.mpls_tag_offset:
+                                            self.mpls_tag_offset+4])[0]
+        tag = ((mpls_tc & 0x7) << 9) | (tag & 0xfffff1ff)
+        self.match.mpls_tc = mpls_tc
+        self._set_4bytes(self.mpls_tag_offset, tag)
+
+    def set_mpls_ttl(self, ttl):
+        if self.mpls_tag_offset is None:
+            return   
+        self._set_1bytes(self.mpls_tag_offset + 3, ttl)
+
+    def dec_mpls_ttl(self):
+        if self.mpls_tag_offset is None:
+            return
+        ttl = struct.unpack("B", self.data[self.mpls_tag_offset + 3])[0]
+        self.set_mpls_ttl(ttl - 1)
+
+    def push_vlan(self, ethertype):
+        if len(self) < 14: 
+            self.logger.error("NOT Pushing a new VLAN tag: packet too short!")
+            pass    # invalid ethernet frame, can't add vlan tag
+
+        # from 4.8.1 of the spec, default values are zero
+        # on a push operation if no VLAN tag already exists
+        l2_type = struct.unpack("!H", self.data[12:14])[0]
+        if ((l2_type == ETHERTYPE_VLAN) or (l2_type == ETHERTYPE_VLAN_QinQ)):
+            current_tag = struct.unpack("!H", self.data[14:16])[0]
+        else:
+            current_tag = 0
+        new_tag = struct.pack('!HH',
+                                  # one of 0x8100 or x88a8
+                                  # could check to enforce this?
+                                  ethertype & 0xffff,
+                                  current_tag
+                                  )
+        self.data = self.data[0:12] + new_tag + self.data[12:len(self.data)]  
+        self.parse()
+
+    def pop_vlan(self):
+        if self.vlan_tag_offset is None:
+            pass
+        self.data = self.data[0:12] + self.data[16:len(self.data)]
+        self.parse()
+
+    def push_mpls(self, ethertype):
+        tag = MplsTag(0, 0, 0)
+        bos = False
+        
+        if self.mpls_tag_offset:
+            # The new tag defaults to the old one.
+            packed_tag = struct.unpack("!I", self.data[self.mpls_tag_offset:
+                                                       self.mpls_tag_offset+4])[0]
+            (tag, _) = MplsTag.unpack(packed_tag)
+            
+        else:
+            # Pushing a new label stack, set the BoS bit and get TTL from IP.
+            bos = True
+            if self.ip_header_offset:
+                ttl = struct.unpack("B", self.data[self.ip_header_offset + \
+                                                       Packet.IP_OFFSET_TTL])[0]
+                tag = MplsTag(0, 0, ttl)
+                                                       
+        self.data = self.data[0:14] + \
+                    struct.pack("!I", tag.pack(bos)) + \
+                    self.data[14:]
+        self._set_2bytes(12, ethertype)   
+        # Reparse to update offsets, ethertype, etc.
+        self.parse()
+            
+    def pop_mpls(self, ethertype):
+        # Ignore if no existing tags.
+        if self.mpls_tag_offset:
+            self.data = self.data[0:self.mpls_tag_offset] + \
+                        self.data[self.mpls_tag_offset + 4:]
+            self._set_2bytes(12, ethertype)
+            
+            # Reparse to update offsets, ethertype, etc.
+            self.parse()
+    
+    def set_nw_ttl(self, ttl):
+        if self.ip_header_offset is None:
+            return
+        self._set_1bytes(self.ip_header_offset + Packet.IP_OFFSET_TTL, ttl)
+        self._update_l4_checksum()
+        # don't need to update self.match; no ttl in it
+
+    def dec_nw_ttl(self):
+        if self.ip_header_offset is None:
+            return
+        offset = self.ip_header_offset + Packet.IP_OFFSET_TTL
+        old_ttl = struct.unpack("b",self.data[offset:offset + 1])[0]
+        self.set_nw_ttl( old_ttl - 1)
+
+    #
+    # All action functions need to take the action object for params
+    # These take an action object to facilitate the switch implementation
+    #
+
+    def action_output(self, action, switch):
+        if action.port < ofp.OFPP_MAX:
+            switch.dataplane.send(action.port, self.data, 
+                                  queue_id=self.queue_id)
+        elif action.port == ofp.OFPP_ALL:
+            for of_port in switch.ports.iterkeys():
+                if of_port != self.in_port: 
+                    switch.dataplane.send(of_port, self.data, 
+                                          queue_id=self.queue_id)
+        elif action.port == ofp.OFPP_IN_PORT:
+            switch.dataplane.send(self.in_port, self.data, 
+                                  queue_id=self.queue_id)
+        else:
+            switch.logger.error("NEED to implement action_output" + 
+                                " for port %d" % action.port)        
+
+    def action_set_queue(self, action, switch):
+        self.set_queue(action.queue_id)
+
+    def action_set_vlan_vid(self, action, switch):
+        self.set_vlan_vid(action.vlan_vid)
+
+    def action_set_vlan_pcp(self, action, switch):
+        self.set_vlan_pcp(action.vlan_pcp)
+
+    def action_set_dl_src(self, action, switch):
+        self.set_dl_src(action.dl_addr)
+
+    def action_set_dl_dst(self, action, switch):
+        self.set_dl_dst(action.dl_addr)
+
+    def action_set_nw_src(self, action, switch):
+        self.set_nw_src(action.nw_addr)
+
+    def action_set_nw_dst(self, action, switch):
+        self.set_nw_dst(action.nw_addr)
+
+    def action_set_nw_tos(self, action, switch):
+        self.set_nw_tos(action.nw_tos)
+
+    def action_set_nw_ecn(self, action, switch):
+        self.set_nw_ecn(action.nw_ecn)
+
+    def action_set_tp_src(self, action, switch):
+        self.set_tp_src(action.tp_port)
+
+    def action_set_tp_dst(self, action, switch):
+        self.set_tp_dst(action.tp_port)
+
+    def action_copy_ttl_out(self, action, switch):
+        self.copy_ttl_out()
+
+    def action_copy_ttl_in(self, action, switch):
+        self.copy_ttl_in()
+
+    def action_set_mpls_label(self, action, switch):
+        self.set_mpls_label(action.mpls_label)
+
+    def action_set_mpls_tc(self, action, switch):
+        self.set_mpls_tc(action.mpls_tc)
+
+    def action_set_mpls_ttl(self, action, switch):
+        self.set_mpls_ttl(action.mpls_ttl)
+
+    def action_dec_mpls_ttl(self, action, switch):
+        self.dec_mpls_ttl()
+
+    def action_push_vlan(self, action, switch):
+        self.push_vlan(action.ethertype)
+
+    def action_pop_vlan(self, action, switch):
+        self.pop_vlan()
+
+    def action_push_mpls(self, action, switch):
+        self.push_mpls(action.ethertype)
+
+    def action_pop_mpls(self, action, switch):
+        self.pop_mpls(action.ethertype)
+    
+    def action_experimenter(self, action, switch):
+        pass
+
+    def action_set_nw_ttl(self, action, switch):
+        self.set_nw_ttl(action.nw_ttl)
+
+    def action_dec_nw_ttl(self, action, switch):
+        self.dec_nw_ttl()
+
+    def action_group(self, action, switch):
+        pass
+
+    def execute_action_set(self, switch):
+        """
+        Execute the actions in the action set for the packet
+        according to the order given in ordered_action_list.
+
+        This determines the order in which
+        actions in the packet's action set are executed
+
+        @param switch The parent switch object (for sending pkts out)
+
+        @todo Verify the ordering in this list
+        """
+        cls = action.action_copy_ttl_in
+        if cls in self.action_set.keys():
+            self.logger.debug("Action copy_ttl_in")
+            self.action_copy_ttl_in(self.action_set[cls], switch)
+
+        cls = action.action_pop_mpls
+        if cls in self.action_set.keys():
+            self.logger.debug("Action pop_mpls")
+            self.action_pop_mpls(self.action_set[cls], switch)
+        cls = action.action_pop_vlan
+        if cls in self.action_set.keys():
+            self.logger.debug("Action pop_vlan")
+            self.action_pop_vlan(self.action_set[cls], switch)
+        cls = action.action_push_mpls
+        if cls in self.action_set.keys():
+            self.logger.debug("Action push_mpls")
+            self.action_push_mpls(self.action_set[cls], switch)
+        cls = action.action_push_vlan
+        if cls in self.action_set.keys():
+            self.logger.debug("Action push_vlan")
+            self.action_push_vlan(self.action_set[cls], switch)
+
+        cls = action.action_dec_mpls_ttl
+        if cls in self.action_set.keys():
+            self.logger.debug("Action dec_mpls_ttl")
+            self.action_dec_mpls_ttl(self.action_set[cls], switch)
+        cls = action.action_dec_nw_ttl
+        if cls in self.action_set.keys():
+            self.logger.debug("Action dec_nw_ttl")
+            self.action_dec_nw_ttl(self.action_set[cls], switch)
+        cls = action.action_copy_ttl_out
+        if cls in self.action_set.keys():
+            self.logger.debug("Action copy_ttl_out")
+            self.action_copy_ttl_out(self.action_set[cls], switch)
+
+        cls = action.action_set_dl_dst
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_dl_dst")
+            self.action_set_dl_dst(self.action_set[cls], switch)
+        cls = action.action_set_dl_src
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_dl_src")
+            self.action_set_dl_src(self.action_set[cls], switch)
+        cls = action.action_set_mpls_label
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_mpls_label")
+            self.action_set_mpls_label(self.action_set[cls], switch)
+        cls = action.action_set_mpls_tc
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_mpls_tc")
+            self.action_set_mpls_tc(self.action_set[cls], switch)
+        cls = action.action_set_mpls_ttl
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_mpls_ttl")
+            self.action_set_mpls_ttl(self.action_set[cls], switch)
+        cls = action.action_set_nw_dst
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_nw_dst")
+            self.action_set_nw_dst(self.action_set[cls], switch)
+        cls = action.action_set_nw_ecn
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_nw_ecn")
+            self.action_set_nw_ecn(self.action_set[cls], switch)
+        cls = action.action_set_nw_src
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_nw_src")
+            self.action_set_nw_src(self.action_set[cls], switch)
+        cls = action.action_set_nw_tos
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_nw_tos")
+            self.action_set_nw_tos(self.action_set[cls], switch)
+        cls = action.action_set_nw_ttl
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_nw_ttl")
+            self.action_set_nw_ttl(self.action_set[cls], switch)
+        cls = action.action_set_queue
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_queue")
+            self.action_set_queue(self.action_set[cls], switch)
+        cls = action.action_set_tp_dst
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_tp_dst")
+            self.action_set_tp_dst(self.action_set[cls], switch)
+        cls = action.action_set_tp_src
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_tp_src")
+            self.action_set_tp_src(self.action_set[cls], switch)
+        cls = action.action_set_vlan_pcp
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_vlan_pcp")
+            self.action_set_vlan_pcp(self.action_set[cls], switch)
+        cls = action.action_set_vlan_vid
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_vlan_vid")
+            self.action_set_vlan_vid(self.action_set[cls], switch)
+
+        cls = action.action_group
+        if cls in self.action_set.keys():
+            self.logger.debug("Action group")
+            self.action_group(self.action_set[cls], switch)
+        cls = action.action_experimenter
+        if cls in self.action_set.keys():
+            self.logger.debug("Action experimenter")
+            self.action_experimenter(self.action_set[cls], switch)
+        cls = action.action_output
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_output")
+            self.action_output(self.action_set[cls], switch)
+
+
+def ascii_ip_to_bin(ip):
+        """ Take '192.168.0.1' and return the NBO decimal equivalent 0xc0a80101 """
+        #Lookup the cleaner, one-line way of doing this
+        # or if there isn't just a library (!?)
+        s = ip.split('.')
+        return struct.unpack("!L", struct.pack("BBBB", int(s[0]), 
+                                               int(s[1]), 
+                                               int(s[2]), 
+                                               int(s[3]) ))[0]
+    
+
+class parse_error(Exception):
+    """
+    Thrown internally if there is an error in packet parsing
+    """
+    
+    def __init__(self, why):
+        self.why = why
+        
+    def __str__(self):
+        return "%s:: %s" % (super.__str__(self), self.why)
+        
+class packet_test(unittest.TestCase):
+    """
+    Unit tests for packet class
+    """
+    
+    def ascii_to_data(self, str):
+        return binascii.unhexlify(str.translate(string.maketrans('',''),
+                                                string.whitespace))
+    
+    def setUp(self):
+        """
+        Simple packet data for parsing tests.  
+
+        Ethernet II, Src: Fujitsu_ef:cd:8d (00:17:42:ef:cd:8d), 
+            Dst: ZhsZeitm_5d:24:00 (00:d0:05:5d:24:00)
+        Internet Protocol, Src: 172.24.74.96 (172.24.74.96), 
+            Dst: 171.64.74.58 (171.64.74.58)
+        Transmission Control Protocol, Src Port: 59581 (59581), 
+            Dst Port: ssh (22), Seq: 2694, Ack: 2749, Len: 48
+        """
+        pktdata = self.ascii_to_data(
+            """00 d0 05 5d 24 00 00 17 42 ef cd 8d 08 00 45 10
+               00 64 65 67 40 00 40 06 e9 29 ac 18 4a 60 ab 40
+               4a 3a e8 bd 00 16 7c 28 2f 88 f2 bd 7a 03 80 18
+               00 b5 ec 49 00 00 01 01 08 0a 00 d1 46 8b 32 ed
+               7c 88 78 4b 8a dc 0a 1f c4 d3 02 a3 ae 1d 3c aa
+               6f 1a 36 9f 27 11 12 71 5b 5d 88 f2 97 fa e7 f9
+               99 c1 9f 9c 7f c5 1e 3e 45 c6 a6 ac ec 0b 87 64
+               98 dd""")
+        self.pkt = Packet(data=pktdata)
+        
+        """
+        MPLS packet data for MPLS parsing tests.  
+
+        Ethernet II, Src: Fujitsu_ef:cd:8d (00:17:42:ef:cd:8d), 
+            Dst: ZhsZeitm_5d:24:00 (00:d0:05:5d:24:00)
+        MPLS, Label: 0xFEFEF, TC: 5, S: 1, TTL: 0xAA
+        Internet Protocol, Src: 172.24.74.96 (172.24.74.96), 
+            Dst: 171.64.74.58 (171.64.74.58)
+        Transmission Control Protocol, Src Port: 59581 (59581), 
+            Dst Port: ssh (22), Seq: 2694, Ack: 2749, Len: 48
+        """
+        mplspktdata = self.ascii_to_data(
+            """00 d0 05 5d 24 00 00 17 42 ef cd 8d 88 47
+               FE FE FB AA
+               45 10 00 64 65 67 40 00 40 06 e9 29 ac 18 4a 60 
+               ab 40 4a 3a 
+               e8 bd 00 16 7c 28 2f 88 f2 bd 7a 03 80 18
+               00 b5 ec 49 00 00 01 01 08 0a 00 d1 46 8b 32 ed
+               7c 88 78 4b 8a dc 0a 1f c4 d3 02 a3 ae 1d 3c aa
+               6f 1a 36 9f 27 11 12 71 5b 5d 88 f2 97 fa e7 f9
+               99 c1 9f 9c 7f c5 1e 3e 45 c6 a6 ac ec 0b 87 64
+               98 dd""")
+        self.mplspkt = Packet(data=mplspktdata)
+
+    def runTest(self):
+        self.assertTrue(self.pkt)
+        
+class l2_parsing_test(packet_test):
+    def runTest(self):
+        match = self.pkt.match
+        self.assertEqual(match.dl_dst,[0x00,0xd0,0x05,0x5d,0x24,0x00])
+        self.assertEqual(match.dl_src,[0x00,0x17,0x42,0xef,0xcd,0x8d])
+        self.assertEqual(match.dl_type,ETHERTYPE_IP)
+        
+class mpls_parsing_test(packet_test):
+    def runTest(self):
+        match = self.mplspkt.match
+        self.assertEqual(match.mpls_label, 0xFEFEF)
+        self.assertEqual(match.mpls_tc, 5)
+
+class ip_parsing_test(packet_test):
+    def runTest(self):
+        match = self.pkt.match
+        # @todo Verify byte ordering of the following
+        self.assertEqual(match.nw_dst,ascii_ip_to_bin('171.64.74.58'))
+        self.assertEqual(match.nw_src,ascii_ip_to_bin('172.24.74.96'))
+        self.assertEqual(match.nw_proto, socket.IPPROTO_TCP)
+
+class mpls_setting_test(packet_test):
+    def runTest(self):
+        orig_len = len(self.mplspkt)
+        label = 0x12345
+        tc = 6
+        ttl = 0x78
+        self.mplspkt.set_mpls_label(label)
+        self.mplspkt.set_mpls_tc(tc)
+        self.mplspkt.set_mpls_ttl(ttl)
+        self.mplspkt.dec_mpls_ttl()
+        self.mplspkt.parse()
+        
+        self.assertEqual(len(self.mplspkt), orig_len)
+        self.assertTrue(self.mplspkt.mpls_tag_offset)
+        match = self.mplspkt.match
+        
+        self.assertEqual(match.mpls_label, label)
+        self.assertEqual(match.mpls_tc, tc)
+        new_ttl = struct.unpack("B", self.mplspkt.data[self.mplspkt.mpls_tag_offset + 3:
+                                                       self.mplspkt.mpls_tag_offset + 4])[0]
+        self.assertEqual(new_ttl, ttl - 1)
+
+class mpls_pop_test(packet_test):
+    def runTest(self):
+        orig_len = len(self.mplspkt)
+        self.mplspkt.pop_mpls(ETHERTYPE_IP)
+        self.mplspkt.parse()
+        
+        self.assertEqual(len(self.mplspkt), orig_len - 4)
+        self.assertFalse(self.mplspkt.mpls_tag_offset)
+        match = self.mplspkt.match
+        
+        self.assertEqual(match.dl_type,ETHERTYPE_IP)
+        self.assertEqual(match.nw_dst,ascii_ip_to_bin('171.64.74.58'))
+        self.assertEqual(match.nw_src,ascii_ip_to_bin('172.24.74.96'))
+        self.assertEqual(match.nw_proto, socket.IPPROTO_TCP)
+        
+class mpls_push_test(packet_test):
+    def runTest(self):
+        orig_len = len(self.pkt)
+        self.pkt.push_mpls(ETHERTYPE_MPLS)
+        self.pkt.parse()
+        
+        self.assertEqual(len(self.pkt), orig_len + 4)
+        self.assertTrue(self.pkt.mpls_tag_offset)
+        match = self.pkt.match
+        
+        self.assertEqual(match.dl_type, ETHERTYPE_MPLS)
+        self.assertEqual(match.mpls_label, 0)
+        self.assertEqual(match.mpls_tc, 0)
+
+class ip_setting_test(packet_test):
+    def runTest(self):
+        orig_len = len(self.pkt)
+        ip1 = '11.22.33.44'
+        ip2 = '55.66.77.88'
+        self.pkt.set_nw_src(ascii_ip_to_bin(ip1))
+        self.pkt.set_nw_dst(ascii_ip_to_bin(ip2))
+        self.pkt.parse()
+        self.assertEqual(len(self.pkt), orig_len)
+        match = self.pkt.match
+        
+        # @todo Verify byte ordering of the following
+        self.assertEqual(match.nw_src,ascii_ip_to_bin(ip1))
+        self.assertEqual(match.nw_dst,ascii_ip_to_bin(ip2))
+        
+
+
+
+class l4_parsing_test(packet_test):
+    def runTest(self):
+        match = self.pkt.match
+        self.assertEqual(match.tp_dst,22)
+        self.assertEqual(match.tp_src,59581)
+
+class l4_setting_test(packet_test):
+    def runTest(self):
+        orig_len = len(self.pkt)
+        self.pkt.set_tp_src(777)
+        self.pkt.set_tp_dst(666)
+        self.pkt.parse()
+        self.assertEqual(len(self.pkt), orig_len)
+        match = self.pkt.match
+        self.assertEqual(match.tp_src,777)
+        self.assertEqual(match.tp_dst,666)
+        
+class simple_tcp_test(unittest.TestCase):
+    """ Make sure that simple_tcp_test does what it should 
+                          pktlen=100, 
+                          dl_dst='00:01:02:03:04:05',
+                          dl_src='00:06:07:08:09:0a',
+                          dl_vlan_enable=False,
+                          dl_vlan=0,
+                          dl_vlan_pcp=0,
+                          dl_vlan_cfi=0,
+                          ip_src='192.168.0.1',
+                          ip_dst='192.168.0.2',
+                          ip_tos=0,
+                          tcp_sport=1234,
+                          tcp_dport=80):
+    """
+    def setUp(self):
+        self.pkt = Packet().simple_tcp_packet()
+        self.pkt.parse()
+        logging.basicConfig(filename="", level=logging.DEBUG)
+        self.logger = logging.getLogger('unittest')
+       
+    def runTest(self):
+        match = self.pkt.match
+        self.assertEqual(match.dl_dst, [0x00, 0x01, 0x02, 0x03, 0x04, 0x05])
+        self.assertEqual(match.dl_src, [0x00, 0x06, 0x07, 0x08, 0x09, 0x0a])
+        self.assertEqual(match.dl_type, ETHERTYPE_IP)
+        self.assertEqual(match.nw_src, ascii_ip_to_bin('192.168.0.1'))
+        self.assertEqual(match.nw_dst, ascii_ip_to_bin('192.168.0.2'))
+        self.assertEqual(match.tp_dst, 80)
+        self.assertEqual(match.tp_src, 1234)
+
+class simple_vlan_test(simple_tcp_test):
+    """ Make sure that simple_tcp_test does what it should with vlans 
+                         
+    """    
+       
+    def runTest(self):
+        self.pkt = Packet().simple_tcp_packet(dl_vlan_enable=True,dl_vlan=0x0abc)
+        self.pkt.parse()
+        match = self.pkt.match
+        #self.logger.debug("Packet=\n%s" % self.pkt.show())
+        self.assertEqual(match.dl_dst, [0x00, 0x01, 0x02, 0x03, 0x04, 0x05])
+        self.assertEqual(match.dl_src, [0x00, 0x06, 0x07, 0x08, 0x09, 0x0a])
+        self.assertEqual(match.dl_type, ETHERTYPE_IP)
+        self.assertEqual(match.nw_src, ascii_ip_to_bin('192.168.0.1'))
+        self.assertEqual(match.nw_dst, ascii_ip_to_bin('192.168.0.2'))
+        self.assertEqual(match.tp_dst, 80)
+        self.assertEqual(match.tp_src, 1234)
+        self.assertEqual(match.dl_vlan, 0xabc)
+        
+class vlan_mod(simple_tcp_test):
+    """ Start with a packet with no vlan, add one, change it, remove it"""
+    def runTest(self):
+        old_len = len(self.pkt)
+        match = self.pkt.match
+        self.assertEqual(match.dl_vlan, 0xffff)
+        self.assertEqual(len(self.pkt), old_len)
+        #self.logger.debug("PKT=\n" + self.pkt.show())
+        self.pkt.push_vlan(ETHERTYPE_VLAN) # implicitly pushes vid=0
+        self.assertEqual(len(self.pkt), old_len + 4)
+        self.assertEqual(match.dl_vlan, 0)
+        #self.logger.debug("PKT=\n" + self.pkt.show())
+        self.assertEqual(match.dl_type,ETHERTYPE_IP)
+        self.pkt.set_vlan_vid(0xbabe)
+        self.assertEqual(match.dl_vlan, 0x0abe)
+
+class simple_tcp_with_mpls_test(unittest.TestCase):
+    """ Make sure that simple_tcp_packet does what it should 
+                          pktlen=100, 
+                          dl_dst='00:01:02:03:04:05',
+                          dl_src='00:06:07:08:09:0a',
+                          dl_vlan_enable=False,
+                          dl_vlan=0,
+                          dl_vlan_pcp=0,
+                          dl_vlan_cfi=0,
+                          ip_src='192.168.0.1',
+                          ip_dst='192.168.0.2',
+                          ip_tos=0,
+                          tcp_sport=1234,
+                          tcp_dport=80):
+    """
+    def setUp(self):
+        tag1 = MplsTag(0xabcde, 0x5, 0xAA)
+        tag2 = MplsTag(0x54321, 0x2, 0xBB)
+        mpls_tags = (tag1, tag2)        
+        
+        self.pkt = Packet().simple_tcp_packet(mpls_type=ETHERTYPE_MPLS,
+                                              mpls_tags=mpls_tags)
+        self.pkt.parse()
+       
+    def runTest(self):
+        match = self.pkt.match
+        self.assertEqual(match.dl_dst, [0x00, 0x01, 0x02, 0x03, 0x04, 0x05])
+        self.assertEqual(match.dl_src, [0x00, 0x06, 0x07, 0x08, 0x09, 0x0a])
+        self.assertEqual(match.dl_type, ETHERTYPE_MPLS)
+        self.assertEqual(match.mpls_label, 0xabcde)
+        self.assertEqual(match.mpls_tc, 0x5)
+
+if __name__ == '__main__':
+    print("Running packet tests\n")
+    unittest.main()
+
diff --git a/Fabric/Utilities/src/python/oftest/oft12/testutils.py b/Fabric/Utilities/src/python/oftest/oft12/testutils.py
new file mode 100644
index 0000000..3ce2e75
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/oft12/testutils.py
@@ -0,0 +1,1518 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+
+import sys
+import logging
+from cStringIO import StringIO
+#import types
+
+import ofp
+import oftest.parse as parse
+from packet import Packet
+
+try:
+    logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
+    from scapy.all import *
+    from oftest.mpls import *
+except ImportError:
+    sys.exit("Need to install scapy for packet parsing")
+
+global skipped_test_count
+skipped_test_count = 0
+
+# Some useful defines
+IP_ETHERTYPE = 0x800
+IPV6_ETHERTYPE = 0x86dd
+ETHERTYPE_VLAN = 0x8100
+ETHERTYPE_MPLS = 0x8847
+TCP_PROTOCOL = 0x6
+UDP_PROTOCOL = 0x11
+ICMPV6_PROTOCOL = 0x3a
+
+
+
+def clear_switch(parent, port_list, logger):
+    """
+    Clear the switch configuration
+
+    @param parent Object implementing controller and assert equal
+    @param logger Logging object
+    """
+    parent.assertTrue(len(port_list) > 2, "Not enough ports for test")
+    for port in port_list:
+        clear_port_config(parent, port, logger)
+    initialize_table_config(parent.controller, logger)
+    delete_all_flows(parent.controller, logger)
+    delete_all_groups(parent.controller, logger)
+
+    return port_list
+
+def initialize_table_config(ctrl, logger):
+    """
+    Initialize all table configs to default setting ("CONTROLLER")
+    @param ctrl The controller object for the test
+    """
+    logger.info("Initializing all table configs")
+    request = ofp.message.table_mod()  
+    request.config = ofp.OFPTC_TABLE_MISS_CONTROLLER
+    rv = 0
+    for table_id in [0, 1, 2, 3, 4, 5, 6, 7]:
+        request.table_id = table_id
+        rv |= ctrl.message_send(request)
+    return rv
+
+def delete_all_flows(ctrl, logger):
+    """
+    Delete all flows on the switch
+    @param ctrl The controller object for the test
+    @param logger Logging object
+    """
+
+    logger.info("Deleting all flows")
+    #DEFAULT_TABLE_COUNT = 4
+    return delete_all_flows_one_table(ctrl, logger, table_id=0xff)
+
+def delete_all_flows_one_table(ctrl, logger, table_id=0):
+    """
+    Delete all flows on a table
+    @param ctrl The controller object for the test
+    @param logger Logging object
+    @param table_id Table ID
+    """
+    logger.info("Deleting all flows on table ID: " + str(table_id))
+    msg = ofp.message.flow_delete()
+    msg.out_port = ofp.OFPP_ANY
+    msg.out_group = ofp.OFPG_ANY
+    msg.buffer_id = 0xffffffff
+    msg.table_id = table_id
+    logger.debug(msg.show())
+
+    return ctrl.message_send(msg)
+
+def delete_all_groups(ctrl, logger):
+    """
+    Delete all groups on the switch
+    @param ctrl The controller object for the test
+    @param logger Logging object
+    """
+    
+    logger.info("Deleting all groups")
+    msg = ofp.message.group_mod()
+    msg.group_id = ofp.OFPG_ALL
+    msg.command = ofp.OFPGC_DELETE
+    logger.debug(msg.show())
+    return ctrl.message_send(msg)
+
+def clear_port_config(parent, port, logger):
+    """
+    Clear the port configuration 
+
+    @param parent Object implementing controller and assert equal
+    @param logger Logging object
+    """
+    rv = port_config_set(parent.controller, port,
+                         0, 0, logger)
+    parent.assertEqual(rv, 0, "Failed to reset port config")
+
+def simple_tcp_packet(dl_dst='00:01:02:03:04:05',
+                      dl_src='00:06:07:08:09:0a',
+                      vlan_tags=[],  # {type,vid,pcp,cfi}  TODO type
+                      mpls_tags=[],  # {type,label,tc,ttl} TODO type 
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      tcp_sport=1234,
+                      tcp_dport=80,
+                      payload_len = 46):
+    pkt = Ether(dst=dl_dst, src=dl_src)
+
+    vlans_num = 0
+    while len(vlan_tags):
+        tag = vlan_tags.pop(0)
+        dot1q = Dot1Q()
+        if 'vid' in tag:
+            dot1q.vlan = tag['vid']
+        if 'pcp' in tag:
+            dot1q.prio = tag['pcp']
+        if 'cfi' in tag:
+            dot1q.id = tag['cfi']
+        pkt = pkt / dot1q 
+        if 'type' in tag:
+            if vlans_num == 0:
+                pkt[Ether].setfieldval('type', tag['type'])
+            else:
+                pkt[Dot1Q:vlans_num].setfieldval('type', tag['type'])
+        vlans_num+=1
+
+    mplss_num = 0
+    while len(mpls_tags):
+        tag = mpls_tags.pop(0)
+        mpls = MPLS()
+        if 'label' in tag:
+            mpls.label = tag['label']
+        if 'tc' in tag:
+            mpls.cos = tag['tc']
+        if 'ttl' in tag:
+            mpls.ttl = tag['ttl']
+        pkt = pkt / mpls
+        if 'type' in tag:
+            if mplss_num == 0:
+                if vlans_num == 0:
+                    pkt[Ether].setfieldval('type', tag['type'])
+                else:
+                    pkt[Dot1Q:vlans_num].setfieldval('type', tag['type'])
+        mplss_num+=1
+
+    pkt = pkt / IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl) \
+              / TCP(sport=tcp_sport, dport=tcp_dport)
+    
+    pkt = pkt / ("D" * payload_len)
+
+    return pkt
+
+def simple_icmp_packet(dl_dst='00:01:02:03:04:05',
+                       dl_src='00:06:07:08:09:0a',
+                       vlan_tags=[],  # {type,vid,pcp,cfi}  TODO type
+                       mpls_tags=[],  # {type,label,tc,ttl} TODO type 
+                       ip_src='192.168.0.1',
+                       ip_dst='192.168.0.2',
+                       ip_tos=0,
+                       ip_ttl=64,
+                       icmp_type=8, # ICMP_ECHO_REQUEST
+                       icmp_code=0,
+                       payload_len=0):
+
+    #TODO simple_ip_packet
+    pkt = Ether(dst=dl_dst, src=dl_src)
+
+    vlans_num = 0
+    while len(vlan_tags):
+        tag = vlan_tags.pop(0)
+        dot1q = Dot1Q()
+        if 'vid' in tag:
+            dot1q.vlan = tag['vid']
+        if 'pcp' in tag:
+            dot1q.prio = tag['pcp']
+        if 'cfi' in tag:
+            dot1q.id = tag['cfi']
+        pkt = pkt / dot1q 
+        if 'type' in tag:
+            if vlans_num == 0:
+                pkt[Ether].setfieldval('type', tag['type'])
+            else:
+                pkt[Dot1Q:vlans_num].setfieldval('type', tag['type'])
+        vlans_num+=1
+
+    mplss_num = 0
+    while len(mpls_tags):
+        tag = mpls_tags.pop(0)
+        mpls = MPLS()
+        if 'label' in tag:
+            mpls.label = tag['label']
+        if 'tc' in tag:
+            mpls.cos = tag['tc']
+        if 'ttl' in tag:
+            mpls.ttl = tag['ttl']
+        pkt = pkt / mpls
+        if 'type' in tag:
+            if mplss_num == 0:
+                if vlans_num == 0:
+                    pkt[Ether].setfieldval('type', tag['type'])
+                else:
+                    pkt[Dot1Q:vlans_num].setfieldval('type', tag['type'])
+        mplss_num+=1
+
+    pkt = pkt / IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl) \
+              / ICMP(type=icmp_type, code=icmp_code)
+
+    pkt = pkt / ("D" * payload_len)
+
+    return pkt
+
+def simple_ipv6_packet(pktlen=100, 
+                      dl_dst='00:01:02:03:04:05',
+                      dl_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      dl_vlan=0,
+                      dl_vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      ip_src='fe80::2420:52ff:fe8f:5189',
+                      ip_dst='fe80::2420:52ff:fe8f:5190',
+                      ip_tos=0,
+                      tcp_sport=0,
+                      tcp_dport=0, 
+                      EH = False, 
+                      EHpkt = IPv6ExtHdrDestOpt()
+                      ):
+
+    """
+    Return a simple IPv6 packet 
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param dl_dst Destinatino MAC
+    @param dl_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param dl_vlan VLAN ID
+    @param dl_vlan_pcp VLAN priority
+    @param ip_src IPv6 source
+    @param ip_dst IPv6 destination
+    @param ip_tos IP ToS
+    @param tcp_dport TCP destination port
+    @param ip_sport TCP source port
+
+    """
+    # Note Dot1Q.id is really CFI
+    if (dl_vlan_enable):
+        pkt = Ether(dst=dl_dst, src=dl_src)/ \
+            Dot1Q(prio=dl_vlan_pcp, id=dl_vlan_cfi, vlan=dl_vlan)/ \
+            IPv6(src=ip_src, dst=ip_dst)
+
+    else:
+        pkt = Ether(dst=dl_dst, src=dl_src)/ \
+            IPv6(src=ip_src, dst=ip_dst)
+
+    # Add IPv6 Extension Headers 
+    if EH:
+        pkt = pkt / EHpkt
+
+    if (tcp_sport >0 and tcp_dport >0):
+        pkt = pkt / TCP(sport=tcp_sport, dport=tcp_dport)
+
+    if pktlen > len(pkt) :
+        pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_icmpv6_packet(pktlen=100, 
+                      dl_dst='00:01:02:03:04:05',
+                      dl_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      dl_vlan=0,
+                      dl_vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      ip_src='fe80::2420:52ff:fe8f:5189',
+                      ip_dst='fe80::2420:52ff:fe8f:5190',
+                      ip_tos=0,
+                      tcp_sport=0,
+                      tcp_dport=0, 
+                      EH = False, 
+                      EHpkt = IPv6ExtHdrDestOpt(),
+                      route_adv = False,
+                      sll_enabled = False
+                      ):
+
+    """
+    Return a simple dataplane ICMPv6 packet 
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param dl_dst Destinatino MAC
+    @param dl_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param dl_vlan VLAN ID
+    @param dl_vlan_pcp VLAN priority
+    @param ip_src IPv6 source
+    @param ip_dst IPv6 destination
+    @param ip_tos IP ToS
+    @param tcp_dport TCP destination port
+    @param ip_sport TCP source port
+    
+    """
+    if (dl_vlan_enable):
+        pkt = Ether(dst=dl_dst, src=dl_src)/ \
+            Dot1Q(prio=dl_vlan_pcp, id=dl_vlan_cfi, vlan=dl_vlan)/ \
+            IPv6(src=ip_src, dst=ip_dst)
+
+    else:
+        pkt = Ether(dst=dl_dst, src=dl_src)/ \
+            IPv6(src=ip_src, dst=ip_dst)
+            
+            
+    # Add IPv6 Extension Headers 
+    if EH:
+        pkt = pkt / EHpkt
+
+    if route_adv:
+        pkt = pkt/ \
+        ICMPv6ND_RA(chlim=255, H=0L, M=0L, O=1L, routerlifetime=1800, P=0L, retranstimer=0, prf=0L, res=0L)/ \
+        ICMPv6NDOptPrefixInfo(A=1L, res2=0, res1=0L, L=1L, len=4, prefix='fd00:141:64:1::', R=0L, validlifetime=1814400, prefixlen=64, preferredlifetime=604800, type=3)
+        if sll_enabled :
+            pkt = pkt/ \
+            ICMPv6NDOptSrcLLAddr(type=1, len=1, lladdr='66:6f:df:2d:7c:9c')
+    else :
+        pkt = pkt/ \
+            ICMPv6EchoRequest()
+    if (tcp_sport >0 and tcp_dport >0):
+        pkt = pkt / TCP(sport=tcp_sport, dport=tcp_dport)
+
+    if pktlen > len(pkt) :
+        pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+
+def do_barrier(ctrl):
+    b = ofp.message.barrier_request()
+    ctrl.transact(b)
+
+
+def port_config_get(controller, port_no, logger):
+    """
+    Get a port's configuration
+
+    Gets the switch feature configuration and grabs one port's
+    configuration
+
+    @returns (hwaddr, config, advert) The hwaddress, configuration and
+    advertised values
+    """
+    request = ofp.message.features_request()
+    reply, _ = controller.transact(request, timeout=2)
+    if reply is None:
+        logger.warn("Get feature request failed")
+        return None, None, None
+    logger.debug(reply.show())
+    for idx in range(len(reply.ports)):
+        if reply.ports[idx].port_no == port_no:
+            return (reply.ports[idx].hw_addr, reply.ports[idx].config,
+                    reply.ports[idx].advertised)
+    
+    logger.warn("Did not find port number for port config")
+    return None, None, None
+
+def port_config_set(controller, port_no, config, mask, logger):
+    """
+    Set the port configuration according the given parameters
+
+    Gets the switch feature configuration and updates one port's
+    configuration value according to config and mask
+    """
+    logger.info("Setting port " + str(port_no) + " to config " + str(config))
+    request = ofp.message.features_request()
+    reply, _ = controller.transact(request, timeout=2)
+    if reply is None:
+        return -1
+    logger.debug(reply.show())
+    for idx in range(len(reply.ports)):
+        if reply.ports[idx].port_no == port_no:
+            break
+    if idx >= len(reply.ports):
+        return -1
+    mod = ofp.message.port_mod()
+    mod.port_no = port_no
+    mod.hw_addr = reply.ports[idx].hw_addr
+    mod.config = config
+    mod.mask = mask
+    mod.advertise = reply.ports[idx].advertised
+    rv = controller.message_send(mod)
+    return rv
+
+def receive_pkt_check(dataplane, pkt, yes_ports, no_ports, assert_if, logger):
+    """
+    Check for proper receive packets across all ports
+    @param dataplane The dataplane object
+    @param pkt Expected packet; may be None if yes_ports is empty
+    @param yes_ports Set or list of ports that should recieve packet
+    @param no_ports Set or list of ports that should not receive packet
+    @param assert_if Object that implements assertXXX
+    """
+    for ofport in yes_ports:
+        logger.debug("Checking for pkt on port " + str(ofport))
+        (_, rcv_pkt, _) = dataplane.poll(
+            port_number=ofport, timeout=1)
+        assert_if.assertTrue(rcv_pkt is not None, 
+                             "Did not receive pkt on " + str(ofport))
+        assert_if.assertEqual(str(pkt), str(rcv_pkt),
+                              "Response packet does not match send packet " +
+                              "on port " + str(ofport))
+
+    for ofport in no_ports:
+        logger.debug("Negative check for pkt on port " + str(ofport))
+        (_, rcv_pkt, _) = dataplane.poll(
+            port_number=ofport, timeout=1)
+        assert_if.assertTrue(rcv_pkt is None, 
+                             "Unexpected pkt on port " + str(ofport))
+
+
+def pkt_verify(parent, rcv_pkt, exp_pkt):
+    if str(exp_pkt) != str(rcv_pkt):
+        logging.error("ERROR: Packet match failed.")
+        logging.debug("Expected (" + str(len(exp_pkt)) + ")")
+        logging.debug(str(exp_pkt).encode('hex'))
+        sys.stdout = tmpout = StringIO()
+        exp_pkt.show()
+        sys.stdout = sys.__stdout__
+        logging.debug(tmpout.getvalue())
+        logging.debug("Received (" + str(len(rcv_pkt)) + ")")
+        logging.debug(str(rcv_pkt).encode('hex'))
+        sys.stdout = tmpout = StringIO()
+        Ether(rcv_pkt).show()
+        sys.stdout = sys.__stdout__
+        logging.debug(tmpout.getvalue())
+    parent.assertEqual(str(exp_pkt), str(rcv_pkt),
+                       "Packet match error")
+    
+    return rcv_pkt
+
+def receive_pkt_verify(parent, egr_port, exp_pkt):
+    """
+    Receive a packet and verify it matches an expected value
+
+    parent must implement dataplane, assertTrue and assertEqual
+    """
+    (rcv_port, rcv_pkt, _) = parent.dataplane.poll(port_number=egr_port,
+                                                          timeout=1)
+
+    if exp_pkt is None:
+        if rcv_pkt is None:
+            return None
+        else:
+            logging.error("ERROR: Received unexpected packet from " + str(egr_port));
+            return rcv_pkt
+
+    if rcv_pkt is None:
+        logging.error("ERROR: No packet received from " + str(egr_port))
+
+    parent.assertTrue(rcv_pkt is not None,
+                      "Did not receive packet port " + str(egr_port))
+    logging.debug("Packet len " + str(len(rcv_pkt)) + " in on " + 
+                    str(rcv_port))
+
+    return pkt_verify(parent, rcv_pkt, exp_pkt)
+
+def packetin_verify(parent, exp_pkt):
+    """
+    Receive packet_in and verify it matches an expected value
+    """
+    (response, _) = parent.controller.poll(ofp.OFPT_PACKET_IN, 2)
+
+    parent.assertTrue(response is not None, 'Packet in ofp.message not received')
+    if str(exp_pkt) != response.data:
+        logging.debug("pkt  len " + str(len(str(exp_pkt))) + ": "
+                            + str(exp_pkt).encode('hex'))
+        logging.debug("resp len " + str(len(str(response.data))) + ": "
+                            + str(response.data).encode('hex'))
+    parent.assertEqual(str(exp_pkt), response.data,
+                     'PACKET_IN packet does not match send packet')
+
+def match_verify(parent, req_match, res_match):
+    """
+    Verify flow matches agree; if they disagree, report where
+
+    parent must implement assertEqual
+    Use str() to ensure content is compared and not pointers
+    """
+
+    parent.assertEqual(req_match.wildcards, res_match.wildcards,
+                       'Match failed: wildcards: ' + hex(req_match.wildcards) +
+                       " != " + hex(res_match.wildcards))
+    parent.assertEqual(req_match.in_port, res_match.in_port,
+                       'Match failed: in_port: ' + str(req_match.in_port) +
+                       " != " + str(res_match.in_port))
+    parent.assertEqual(str(req_match.dl_src), str(res_match.dl_src),
+                       'Match failed: dl_src: ' + str(req_match.dl_src) +
+                       " != " + str(res_match.dl_src))
+    parent.assertEqual(str(req_match.dl_dst), str(res_match.dl_dst),
+                       'Match failed: dl_dst: ' + str(req_match.dl_dst) +
+                       " != " + str(res_match.dl_dst))
+    parent.assertEqual(req_match.dl_vlan, res_match.dl_vlan,
+                       'Match failed: dl_vlan: ' + str(req_match.dl_vlan) +
+                       " != " + str(res_match.dl_vlan))
+    parent.assertEqual(req_match.dl_vlan_pcp, res_match.dl_vlan_pcp,
+                       'Match failed: dl_vlan_pcp: ' + 
+                       str(req_match.dl_vlan_pcp) + " != " + 
+                       str(res_match.dl_vlan_pcp))
+    parent.assertEqual(req_match.dl_type, res_match.dl_type,
+                       'Match failed: dl_type: ' + str(req_match.dl_type) +
+                       " != " + str(res_match.dl_type))
+
+    if (not(req_match.wildcards & ofp.OFPFW_DL_TYPE)
+        and (req_match.dl_type == IP_ETHERTYPE)):
+        parent.assertEqual(req_match.nw_tos, res_match.nw_tos,
+                           'Match failed: nw_tos: ' + str(req_match.nw_tos) +
+                           " != " + str(res_match.nw_tos))
+        parent.assertEqual(req_match.nw_proto, res_match.nw_proto,
+                           'Match failed: nw_proto: ' + str(req_match.nw_proto) +
+                           " != " + str(res_match.nw_proto))
+        parent.assertEqual(req_match.nw_src, res_match.nw_src,
+                           'Match failed: nw_src: ' + str(req_match.nw_src) +
+                           " != " + str(res_match.nw_src))
+        parent.assertEqual(req_match.nw_dst, res_match.nw_dst,
+                           'Match failed: nw_dst: ' + str(req_match.nw_dst) +
+                           " != " + str(res_match.nw_dst))
+
+        if (not(req_match.wildcards & ofp.OFPFW_NW_PROTO)
+            and ((req_match.nw_proto == TCP_PROTOCOL)
+                 or (req_match.nw_proto == UDP_PROTOCOL))):
+            parent.assertEqual(req_match.tp_src, res_match.tp_src,
+                               'Match failed: tp_src: ' + 
+                               str(req_match.tp_src) +
+                               " != " + str(res_match.tp_src))
+            parent.assertEqual(req_match.tp_dst, res_match.tp_dst,
+                               'Match failed: tp_dst: ' + 
+                               str(req_match.tp_dst) +
+                               " != " + str(res_match.tp_dst))
+
+def flow_removed_verify(parent, request=None, pkt_count=-1, byte_count=-1):
+    """
+    Receive a flow removed msg and verify it matches expected
+
+    @params parent Must implement controller, assertEqual
+    @param pkt_count If >= 0, verify packet count
+    @param byte_count If >= 0, verify byte count
+    """
+    (response, _) = parent.controller.poll(ofp.OFPT_FLOW_REMOVED, 2)
+    parent.assertTrue(response is not None, 'No flow removed ofp.message received')
+
+    if request is None:
+        return
+
+    parent.assertEqual(request.cookie, response.cookie,
+                       "Flow removed cookie error: " +
+                       hex(request.cookie) + " != " + hex(response.cookie))
+
+    req_match = request.match
+    res_match = response.match
+    verifyMatchField(req_match, res_match)
+
+    if (req_match.wildcards != 0):
+        parent.assertEqual(request.priority, response.priority,
+                           'Flow remove prio mismatch: ' + 
+                           str(request.priority) + " != " + 
+                           str(response.priority))
+        parent.assertEqual(response.reason, ofp.OFPRR_HARD_TIMEOUT,
+                           'Flow remove reason is not HARD TIMEOUT:' +
+                           str(response.reason))
+        if pkt_count >= 0:
+            parent.assertEqual(response.packet_count, pkt_count,
+                               'Flow removed failed, packet count: ' + 
+                               str(response.packet_count) + " != " +
+                               str(pkt_count))
+        if byte_count >= 0:
+            parent.assertEqual(response.byte_count, byte_count,
+                               'Flow removed failed, byte count: ' + 
+                               str(response.byte_count) + " != " + 
+                               str(byte_count))
+def flow_msg_create(parent, pkt, ing_port=0, match_fields=None, instruction_list=None, 
+                    action_list=None,wildcards=0, egr_port=None, 
+                    egr_queue=None, table_id=0, check_expire=False):
+    """
+    Multi-purpose flow_mod creation utility
+
+    Match on packet with given wildcards.  
+    See flow_match_test for other parameter descriptoins
+   
+    if egr_queue is set
+             append an out_queue ofp.action to egr_queue to the actions_list
+    else if egr_port is set:  
+             append an output ofp.action to egr_port to the actions_list
+    if the instruction_list is empty, 
+        append an APPLY ofp.instruction to it
+    Add the action_list to the first write or apply ofp.instruction
+    
+    @param egr_queue if not None, make the output an enqueue ofp.action
+    @param table_id Table ID for writing a flow_mod
+    """
+
+    if match_fields is None:
+        match_fields = parse.packet_to_flow_match(pkt)
+    parent.assertTrue(match_fields is not None, "Flow match from pkt failed")
+    in_port = ofp.oxm.in_port(ing_port)
+    match_fields.oxm_list.append(in_port) 
+    request = ofp.message.flow_add()
+    request.match= match_fields
+    request.buffer_id = 0xffffffff
+    request.table_id = table_id
+    
+    if check_expire:
+        request.flags |= ofp.OFPFF_SEND_FLOW_REM
+        request.hard_timeout = 1    
+    
+    if action_list is None:
+        action_list = []
+    if instruction_list is None:
+        instruction_list = []
+    
+    # Set up output/enqueue ofp.action if directed
+    if egr_queue is not None:
+        parent.assertTrue(egr_port is not None, "Egress port not set")
+        act = ofp.action.set_queue()
+        act.port = egr_port
+        act.queue_id = egr_queue
+        action_list.append(act)
+    elif egr_port is not None:
+        act = ofp.action.output()
+        act.port = egr_port
+        action_list.append(act)
+        
+    inst = None
+    if len(instruction_list) == 0: 
+        inst = ofp.instruction.apply_actions()
+        instruction_list.append(inst)
+    else:
+        for inst in instruction_list:
+            if (inst.type == ofp.OFPIT_WRITE_ACTIONS or
+                inst.type == ofp.OFPIT_APPLY_ACTIONS):
+                break
+
+
+    # add all the actions to the last inst
+    inst.actions += action_list
+
+    # add all the instrutions to the flow_mod
+    request.instructions += instruction_list
+ 
+    logging.debug(request.show())
+    return request
+
+def flow_msg_install(parent, request, clear_table=True):
+    """
+    Install a flow mod ofp.message in the switch
+
+    @param parent Must implement controller, assertEqual, assertTrue
+    @param request The request, all set to go
+    @param clear_table If true, clear the flow table before installing
+    """
+    if clear_table:
+        logging.debug("Clear flow table")
+        if request.table_id:
+            table_id = request.table_id
+        else:
+            table_id = 0
+        rc = delete_all_flows_one_table(parent.controller,
+                                        logging,
+                                        table_id)
+        parent.assertEqual(rc, 0, "Failed to delete all flows on table: "
+                           + str(table_id))
+        do_barrier(parent.controller)
+
+    logging.debug("Insert flow::\n%s" % request.show())
+    rv = parent.controller.message_send(request)
+    parent.assertTrue(rv != -1, "Error installing flow mod")
+    do_barrier(parent.controller)
+
+def error_verify(parent, exp_type, exp_code):
+    """
+    Receive an error msg and verify if it is as expected
+
+    @param parent Must implement controller, assertEqual
+    @param exp_type Expected error type
+    @param exp_code Expected error code
+    """
+    (response, raw) = parent.controller.poll(ofp.OFPT_ERROR, 2)
+    parent.assertTrue(response is not None, 'No error ofp.message received')
+
+    if (exp_type is None) or (exp_code is None):
+        logging.debug("Parametrs are not sufficient")
+        return
+
+    parent.assertEqual(exp_type, response.type,
+                       'Error ofp.message type mismatch: ' +
+                       str(exp_type) + " != " +
+                       str(response.type))
+    parent.assertEqual(exp_code, response.code,
+                       'Error ofp.message code mismatch: ' +
+                       str(exp_code) + " != " +
+                       str(response.code))
+
+def flow_match_test_port_pair(parent, ing_port, egr_port, match=None, 
+                              wildcards=0, mask=None,
+                              dl_vlan=-1, pkt=None, exp_pkt=None,
+                              apply_action_list=None, check_expire=False):
+    """
+    Flow match test on single TCP packet
+
+    Run test with packet through switch from ing_port to egr_port
+    See flow_match_test for parameter descriptions
+    """
+
+    logging.info("Pkt match test: " + str(ing_port) + " to " + str(egr_port))
+    logging.debug("  WC: " + hex(wildcards) + " vlan: " + str(dl_vlan) +
+                    " expire: " + str(check_expire))
+    if pkt is None:
+        if dl_vlan >= 0:
+            pkt = simple_tcp_packet(vlan_tags=[{'vid': dl_vlan}])
+        else:
+            pkt = simple_tcp_packet()
+
+    match = parse.packet_to_flow_match(pkt)
+    parent.assertTrue(match is not None, "Flow match from pkt failed")
+
+    if mask is not None:
+        match.dl_src_mask = mask['dl_src']
+        match.dl_dst_mask = mask['dl_dst']
+        match.nw_src_mask = mask['nw_src']
+        match.nw_dst_mask = mask['nw_dst']
+        #Set unmatching values on corresponding match fields
+        for i in range(ofp.OFP_ETH_ALEN):
+            match.dl_src[i] = match.dl_src[i] ^ match.dl_src_mask[i]
+            match.dl_dst[i] = match.dl_dst[i] ^ match.dl_dst_mask[i]
+        match.nw_src = match.nw_src ^ match.nw_src_mask
+        match.nw_dst = match.nw_dst ^ match.nw_dst_mask
+
+    request = flow_msg_create(parent, pkt, ing_port=ing_port, 
+                              match=match,
+                              wildcards=wildcards, egr_port=egr_port,
+                              action_list=apply_action_list)
+
+    flow_msg_install(parent, request)
+
+    logging.debug("Send packet: " + str(ing_port) + " to " + str(egr_port))
+    parent.dataplane.send(ing_port, str(pkt))
+
+    if exp_pkt is None:
+        exp_pkt = pkt
+    receive_pkt_verify(parent, egr_port, exp_pkt)
+
+    if check_expire:
+        #@todo Not all HW supports both pkt and byte counters
+        flow_removed_verify(parent, request, pkt_count=1, byte_count=len(pkt))
+def flow_match_test(parent, port_map, match=None, wildcards=0,
+                    mask=None, dl_vlan=-1, pkt=None,
+                    exp_pkt=None, apply_action_list=None,
+                    check_expire=False,  max_test=0):
+    """
+    Run flow_match_test_port_pair on all port pairs
+
+    @param max_test If > 0 no more than this number of tests are executed.
+    @param parent Must implement controller, dataplane, assertTrue, assertEqual
+    and logger
+    @param pkt If not None, use this packet for ingress
+    @param match If not None, use this value in flow_mod
+    @param wildcards For flow match entry
+    @param mask DL/NW address bit masks as a dictionary. If set, it is tested
+    against the corresponding match fields with the opposite values
+    @param dl_vlan If not -1, and pkt is None, create a pkt w/ VLAN tag
+    @param exp_pkt If not None, use this as the expected output pkt; els use pkt
+    @param action_list Additional actions to add to flow mod
+    @param check_expire Check for flow expiration ofp.message
+    """
+    of_ports = port_map.keys()
+    of_ports.sort()
+    parent.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+    test_count = 0
+
+    for ing_idx in range(len(of_ports)):
+        ingress_port = of_ports[ing_idx]
+        for egr_idx in range(len(of_ports)):
+            if egr_idx == ing_idx:
+                continue
+            egress_port = of_ports[egr_idx]
+            flow_match_test_port_pair(parent, ingress_port, egress_port, 
+                                      match=match, wildcards=wildcards,
+                                      dl_vlan=dl_vlan, mask=mask,
+                                      pkt=pkt, exp_pkt=exp_pkt,
+                                      apply_action_list=apply_action_list,
+                                      check_expire=check_expire)
+            test_count += 1
+            if (max_test > 0) and (test_count >= max_test):
+                logging.info("Ran " + str(test_count) + " tests; exiting")
+                return
+
+def flow_match_test_port_pair_vlan(parent, ing_port, egr_port, wildcards=0,
+                                   dl_vlan=ofp.OFPVID_NONE, dl_vlan_pcp=0,
+                                   dl_vlan_type=ETHERTYPE_VLAN,
+                                   dl_vlan_int=-1, dl_vlan_pcp_int=0,
+                                   vid_match=ofp.OFPVID_NONE, pcp_match=0,
+                                   exp_vid=-1, exp_pcp=0,
+                                   exp_vlan_type=ETHERTYPE_VLAN,
+                                   match_exp=True,
+                                   add_tag_exp=False,
+                                   exp_msg=ofp.OFPT_FLOW_REMOVED,
+                                   exp_msg_type=0, exp_msg_code=0,
+                                   pkt=None, exp_pkt=None,
+                                   action_list=None, check_expire=False):
+    """
+    Flow match test for various vlan matching patterns on single TCP packet
+
+    Run test with packet through switch from ing_port to egr_port
+    See flow_match_test_vlan for parameter descriptions
+    """
+    logging.info("Pkt match test: " + str(ing_port) + " to " + str(egr_port))
+    logging.debug("  WC: " + hex(wildcards) + " vlan: " + str(dl_vlan) +
+                    " expire: " + str(check_expire))
+    if pkt is None:
+        if dl_vlan >= 0 and dl_vlan != ofp.OFPVID_NONE:
+            if dl_vlan_int >= 0 and dl_vlan_int != ofp.OFPVID_NONE:
+                pkt = simple_tcp_packet(
+                        vlan_tags=[{'type': dl_vlan_type, 'vid': dl_vlan, 'pcp': dl_vlan_pcp},
+                                   {'vid': dl_vlan_int, 'pcp': dl_vlan_pcp_int}])
+            else:
+                pkt = simple_tcp_packet(
+                        vlan_tags=[{'type': dl_vlan_type, 'vid': dl_vlan, 'pcp': dl_vlan_pcp}])
+        else:
+            pkt = simple_tcp_packet()
+
+    if exp_pkt is None:
+        if exp_vid >= 0 and exp_vid != ofp.OFPVID_NONE:
+            if add_tag_exp:
+                if dl_vlan >= 0 and dl_vlan != ofp.OFPVID_NONE:
+                    if dl_vlan_int >= 0 and dl_vlan_int != ofp.OFPVID_NONE:
+                        exp_pkt = simple_tcp_packet(
+                                    vlan_tags=[{'type': exp_vlan_type, 'vid': exp_vid, 'pcp': exp_pcp},
+                                               {'type': dl_vlan_type, 'vid': dl_vlan, 'pcp': dl_vlan_pcp},
+                                               {'vid': dl_vlan_int, 'pcp': dl_vlan_pcp_int}])
+                    else:
+                        exp_pkt = simple_tcp_packet(
+                                    vlan_tags=[{'type': exp_vlan_type, 'vid': exp_vid, 'pcp': exp_pcp},
+                                               {'type': dl_vlan_type, 'vid': dl_vlan, 'pcp': dl_vlan_pcp}])
+                else:
+                    exp_pkt = simple_tcp_packet(
+                                vlan_tags=[{'type': exp_vlan_type, 'vid': exp_vid, 'pcp': exp_pcp}])
+            else:
+                if dl_vlan_int >= 0:
+                    exp_pkt = simple_tcp_packet(
+                                vlan_tags=[{'type': exp_vlan_type, 'vid': exp_vid, 'pcp': exp_pcp},
+                                           {'vid': dl_vlan_int, 'pcp': dl_vlan_pcp_int}])
+
+                else:
+                    exp_pkt = simple_tcp_packet(
+                                vlan_tags=[{'type': exp_vlan_type, 'vid': exp_vid, 'pcp': exp_pcp}])
+        else:
+            #subtract ofp.action
+            if dl_vlan_int >= 0:
+                exp_pkt = simple_tcp_packet(
+                            vlan_tags=[{'vid': dl_vlan_int, 'pcp': dl_vlan_pcp_int}])
+            else:
+                exp_pkt = simple_tcp_packet()
+
+    match = parse.packet_to_flow_match(pkt)
+    parent.assertTrue(match is not None, "Flow match from pkt failed")
+
+    match.dl_vlan = vid_match
+    match.dl_vlan_pcp = pcp_match
+    match.wildcards = wildcards
+
+    request = flow_msg_create(parent, pkt, ing_port=ing_port,
+                              wildcards=wildcards,
+                              match=match,
+                              egr_port=egr_port,
+                              action_list=action_list)
+
+    flow_msg_install(parent, request)
+
+    logging.debug("Send packet: " + str(ing_port) + " to " + str(egr_port))
+    logging.debug("Sent:" + str(pkt).encode('hex'))
+    parent.dataplane.send(ing_port, str(pkt))
+
+    if match_exp:
+        receive_pkt_verify(parent, egr_port, exp_pkt)
+        if check_expire:
+            #@todo Not all HW supports both pkt and byte counters
+            flow_removed_verify(parent, request, pkt_count=1, byte_count=len(pkt))
+    else:
+        if exp_msg is ofp.OFPT_FLOW_REMOVED:
+            if check_expire:
+                flow_removed_verify(parent, request, pkt_count=0, byte_count=0)
+        elif exp_msg is ofp.OFPT_ERROR:
+            error_verify(parent, exp_msg_type, exp_msg_code)
+        else:
+            parent.assertTrue(0, "Rcv: Unexpected ofp.message: " + str(exp_msg))
+
+        (_, rcv_pkt, _) = parent.dataplane.poll(timeout=1)
+        parent.assertFalse(rcv_pkt is not None, "Packet on dataplane")
+
+def flow_match_test_vlan(parent, port_map, wildcards=0,
+                         dl_vlan=ofp.OFPVID_NONE, dl_vlan_pcp=0, dl_vlan_type=ETHERTYPE_VLAN,
+                         dl_vlan_int=-1, dl_vlan_pcp_int=0,
+                         vid_match=ofp.OFPVID_NONE, pcp_match=0,
+                         exp_vid=-1, exp_pcp=0,
+                         exp_vlan_type=ETHERTYPE_VLAN,
+                         match_exp=True,
+                         add_tag_exp=False,
+                         exp_msg=ofp.OFPT_FLOW_REMOVED,
+                         exp_msg_type=0, exp_msg_code=0,
+                         pkt=None, exp_pkt=None,
+                         action_list=None,
+                         check_expire=False,
+                         max_test=0):
+    """
+    Run flow_match_test_port_pair on all port pairs
+
+    @param max_test If > 0 no more than this number of tests are executed.
+    @param parent Must implement controller, dataplane, assertTrue, assertEqual
+    and logger
+    @param wildcards For flow match entry
+    @param dl_vlan If not -1, and pkt is not None, create a pkt w/ VLAN tag
+    @param dl_vlan_pcp VLAN PCP associated with dl_vlan
+    @param dl_vlan_type VLAN ether type associated with dl_vlan
+    @param dl_vlan_int If not -1, create pkt w/ Inner Vlan tag
+    @param dl_vlan_pcp_int VLAN PCP associated with dl_vlan_2nd
+    @param vid_match Matching value for VLAN VID field
+    @param pcp_match Matching value for VLAN PCP field
+    @param exp_vid Expected VLAN VID value. If -1, no VLAN expected
+    @param exp_vlan_type Expected VLAN ether type
+    @param exp_pcp Expected VLAN PCP value
+    @param match_exp Set whether packet is expected to receive
+    @param add_tag_exp If True, expected_packet has an additional vlan tag,
+    If not, expected_packet's vlan tag is replaced as specified
+    @param exp_msg Expected ofp.message
+    @param exp_msg_type Expected ofp.message type associated with the ofp.message
+    @param exp_msg_code Expected ofp.message code associated with the msg_type
+    @param pkt If not None, use this packet for ingress
+    @param exp_pkt If not None, use this as the expected output pkt
+    @param action_list Additional actions to add to flow mod
+    @param check_expire Check for flow expiration ofp.message
+    """
+    of_ports = port_map.keys()
+    of_ports.sort()
+    parent.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+    test_count = 0
+
+    for ing_idx in range(len(of_ports)):
+        ingress_port = of_ports[ing_idx]
+        for egr_idx in range(len(of_ports)):
+            if egr_idx == ing_idx:
+                continue
+            egress_port = of_ports[egr_idx]
+            flow_match_test_port_pair_vlan(parent, ingress_port, egress_port,
+                                           wildcards=wildcards,
+                                           dl_vlan=dl_vlan,
+                                           dl_vlan_pcp=dl_vlan_pcp,
+                                           dl_vlan_type=dl_vlan_type,
+                                           dl_vlan_int=dl_vlan_int,
+                                           dl_vlan_pcp_int=dl_vlan_pcp_int,
+                                           vid_match=vid_match,
+                                           pcp_match=pcp_match,
+                                           exp_vid=exp_vid,
+                                           exp_pcp=exp_pcp,
+                                           exp_vlan_type=exp_vlan_type,
+                                           exp_msg=exp_msg,
+                                           exp_msg_type=exp_msg_type,
+                                           exp_msg_code=exp_msg_code,
+                                           match_exp=match_exp,
+                                           add_tag_exp=add_tag_exp,
+                                           pkt=pkt, exp_pkt=exp_pkt,
+                                           action_list=action_list,
+                                           check_expire=check_expire)
+            test_count += 1
+            if (max_test > 0) and (test_count >= max_test):
+                logging.info("Ran " + str(test_count) + " tests; exiting")
+                return
+
+def test_param_get(config, key, default=None):
+    """
+    Return value passed via test-params if present
+
+    @param config The configuration structure for OFTest
+    @param key The lookup key
+    @param default Default value to use if not found
+
+    If the pair 'key=val' appeared in the string passed to --test-params
+    on the command line, return val (as interpreted by exec).  Otherwise
+    return default value.
+    """
+    try:
+        exec config["test_params"]
+    except:
+        return default
+
+    s = "val = " + str(key)
+    try:
+        val = None
+        exec s
+        return val
+    except:
+        return default
+
+def action_generate(parent, field_to_mod, mod_field_vals):
+    """
+    Create an ofp.action to modify the field indicated in field_to_mod
+
+    @param parent Must implement, assertTrue
+    @param field_to_mod The field to modify as a string name
+    @param mod_field_vals Hash of values to use for modified values
+    """
+
+    act = None
+
+    if field_to_mod in ['pktlen']:
+        return None
+
+    if field_to_mod == 'dl_dst':
+        act = ofp.action.set_dl_dst()
+        act.dl_addr = parse.parse_mac(mod_field_vals['dl_dst'])
+    elif field_to_mod == 'dl_src':
+        act = ofp.action.set_dl_src()
+        act.dl_addr = parse.parse_mac(mod_field_vals['dl_src'])
+    elif field_to_mod == 'vlan_tags':
+        if len(mod_field_vals['vlan_tags']):
+            act = ofp.action.pop_vlan()
+        else:
+            pass
+#    elif field_to_mod == 'dl_vlan_enable':
+#        if not mod_field_vals['dl_vlan_enable']: # Strip VLAN tag
+#            act = ofp.action.pop_vlan()
+#        # Add VLAN tag is handled by dl_vlan field
+#        # Will return None in this case
+#    elif field_to_mod == 'dl_vlan':
+#        act = ofp.action.set_vlan_vid()
+#        act.vlan_vid = mod_field_vals['dl_vlan']
+#    elif field_to_mod == 'dl_vlan_pcp':
+#        act = ofp.action.set_vlan_pcp()
+#        act.vlan_pcp = mod_field_vals['dl_vlan_pcp']
+    elif field_to_mod == 'ip_src':
+        act = ofp.action.set_nw_src()
+        act.nw_addr = parse.parse_ip(mod_field_vals['ip_src'])
+    elif field_to_mod == 'ip_dst':
+        act = ofp.action.set_nw_dst()
+        act.nw_addr = parse.parse_ip(mod_field_vals['ip_dst'])
+    elif field_to_mod == 'ip_tos':
+        act = ofp.action.set_nw_tos()
+        act.nw_tos = mod_field_vals['ip_tos']
+    elif field_to_mod == 'tcp_sport':
+        act = ofp.action.set_tp_src()
+        act.tp_port = mod_field_vals['tcp_sport']
+    elif field_to_mod == 'tcp_dport':
+        act = ofp.action.set_tp_dst()
+        act.tp_port = mod_field_vals['tcp_dport']
+    else:
+        parent.assertTrue(0, "Unknown field to modify: " + str(field_to_mod))
+
+    return act
+
+def pkt_action_setup(parent, start_field_vals={}, mod_field_vals={}, 
+                     mod_fields={}, check_test_params=False):
+    """
+    Set up the ingress and expected packet and ofp.action list for a test
+
+    @param parent Must implement, assertTrue, config hash and logger
+    @param start_field_values Field values to use for ingress packet (optional)
+    @param mod_field_values Field values to use for modified packet (optional)
+    @param mod_fields The list of fields to be modified by the switch in the test.
+    @params check_test_params If True, will check the parameters vid, add_vlan
+    and strip_vlan from the command line.
+
+    Returns a triple:  pkt-to-send, expected-pkt, ofp.action-list
+    """
+
+    new_actions = []
+
+
+    base_pkt_params = {}
+    base_pkt_params['dl_dst'] = '00:DE:F0:12:34:56'
+    base_pkt_params['dl_src'] = '00:23:45:67:89:AB'
+#    base_pkt_params['dl_vlan_enable'] = False
+#    base_pkt_params['dl_vlan'] = 2
+#    base_pkt_params['dl_vlan_pcp'] = 0
+    base_pkt_params['ip_src'] = '192.168.0.1'
+    base_pkt_params['ip_dst'] = '192.168.0.2'
+    base_pkt_params['ip_tos'] = 0
+    base_pkt_params['tcp_sport'] = 1234
+    base_pkt_params['tcp_dport'] = 80
+    for keyname in start_field_vals.keys():
+        base_pkt_params[keyname] = start_field_vals[keyname]
+
+    mod_pkt_params = {}
+    mod_pkt_params['dl_dst'] = '00:21:0F:ED:CB:A9'
+    mod_pkt_params['dl_src'] = '00:ED:CB:A9:87:65'
+#    mod_pkt_params['dl_vlan_enable'] = False
+#    mod_pkt_params['dl_vlan'] = 3
+#    mod_pkt_params['dl_vlan_pcp'] = 7
+    mod_pkt_params['ip_src'] = '10.20.30.40'
+    mod_pkt_params['ip_dst'] = '50.60.70.80'
+    mod_pkt_params['ip_tos'] = 0xf0
+    mod_pkt_params['tcp_sport'] = 4321
+    mod_pkt_params['tcp_dport'] = 8765
+    for keyname in mod_field_vals.keys():
+        mod_pkt_params[keyname] = mod_field_vals[keyname]
+
+    # Check for test param modifications
+    strip = False
+    if check_test_params:
+        add_vlan = test_param_get(parent.config, 'add_vlan')
+        strip_vlan = test_param_get(parent.config, 'strip_vlan')
+        vid = test_param_get(parent.config, 'vid')
+
+        if add_vlan and strip_vlan:
+            parent.assertTrue(0, "Add and strip VLAN both specified")
+
+        if vid:
+            base_pkt_params['dl_vlan_enable'] = True
+            base_pkt_params['dl_vlan'] = vid
+            if 'dl_vlan' in mod_fields:
+                mod_pkt_params['dl_vlan'] = vid + 1
+
+        if add_vlan:
+            base_pkt_params['dl_vlan_enable'] = False
+            mod_pkt_params['dl_vlan_enable'] = True
+            mod_pkt_params['pktlen'] = base_pkt_params['pktlen'] + 4
+            mod_fields.append('pktlen')
+            mod_fields.append('dl_vlan_enable')
+            if 'dl_vlan' not in mod_fields:
+                mod_fields.append('dl_vlan')
+        elif strip_vlan:
+            base_pkt_params['dl_vlan_enable'] = True
+            mod_pkt_params['dl_vlan_enable'] = False
+            mod_pkt_params['pktlen'] = base_pkt_params['pktlen'] - 4
+            mod_fields.append('dl_vlan_enable')
+            mod_fields.append('pktlen')
+
+    # Build the ingress packet
+    ingress_pkt = simple_tcp_packet(**base_pkt_params)
+
+    # Build the expected packet, modifying the indicated fields
+    for item in mod_fields:
+        base_pkt_params[item] = mod_pkt_params[item]
+        act = action_generate(parent, item, mod_pkt_params)
+        if act:
+            new_actions.append(act)
+
+    expected_pkt = simple_tcp_packet(**base_pkt_params)
+
+    return (ingress_pkt, expected_pkt, new_actions)
+        
+def wildcard_all_set(match):
+    match.wildcards = ofp.OFPFW_ALL
+    match.nw_dst_mask = 0xffffffff
+    match.nw_src_mask = 0xffffffff
+    match.dl_dst_mask = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
+    match.dl_src_mask = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
+    match.metadata_mask = 0xffffffffffffffff
+
+def skip_message_emit(parent, s):
+    """
+    Print out a 'skipped' ofp.message to stderr
+
+    @param s The string to print out to the log file
+    @param parent Must implement config and logger objects
+    """
+    global skipped_test_count
+
+    skipped_test_count += 1
+    logging.info("Skipping: " + s)
+    if parent.config["debug"] < logging.WARNING:
+        sys.stderr.write("(skipped) ")
+    else:
+        sys.stderr.write("(S)")
+
+def do_echo_request_reply_test(test,controller):
+        request = ofp.message.echo_request()
+        response, _ = controller.transact(request)
+        test.assertEqual(response.type, ofp.OFPT_ECHO_REPLY,
+                         'response is not echo_reply')
+        test.assertEqual(request.xid, response.xid,
+                         'response xid != request xid')
+        test.assertEqual(len(response.data), 0, 'response data non-empty')
+
+def match_all_generate():
+    match = ofp.ofp_match()
+    return match
+
+def simple_tcp_packet_w_mpls(
+                      dl_dst='00:01:02:03:04:05',
+                      dl_src='00:06:07:08:09:0a',
+                      mpls_type=0x8847,
+                      mpls_label=-1,
+                      mpls_tc=0,
+                      mpls_ttl=64,
+                      mpls_label_int=-1,
+                      mpls_tc_int=0,
+                      mpls_ttl_int=32,
+                      mpls_label_ext=-1,
+                      mpls_tc_ext=0,
+                      mpls_ttl_ext=128,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=192,
+                      tcp_sport=1234,
+                      tcp_dport=80
+                      ):
+    """
+    Return a simple dataplane TCP packet w/wo MPLS tags
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param dl_dst Destinatino MAC
+    @param dl_src Source MAC
+    @param mpls_type MPLS type as ether type
+    @param mpls_label MPLS LABEL if not -1
+    @param mpls_tc MPLS TC
+    @param mpls_ttl MPLS TTL
+    @param mpls_label_int Inner MPLS LABEL if not -1. The shim will be added
+    inside of mpls_label shim.
+    @param mpls_tc_int Inner MPLS TC
+    @param mpls_ttl_int Inner MPLS TTL
+    @param mpls_label_ext External MPLS LABEL if not -1. The shim will be
+    added outside of mpls_label shim
+    @param mpls_tc_ext External MPLS TC
+    @param mpls_ttl_ext External MPLS TTL
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param tcp_dport TCP destination port
+    @param ip_sport TCP source port
+
+    Generates a simple MPLS/IP/TCP request.  Users
+    shouldn't assume anything about this packet other than that
+    it is a valid ethernet/IP/TCP frame.
+    """
+    
+    mpls_tags = []
+    
+    if mpls_label_ext >= 0:
+        mpls_tags.append({'type': mpls_type, 'label': mpls_label_ext, 'tc': mpls_tc_ext, 'ttl': mpls_ttl_ext})
+        
+    if mpls_label >= 0:
+        mpls_tags.append({'type': mpls_type, 'label': mpls_label, 'tc': mpls_tc, 'ttl': mpls_ttl})
+        
+    if mpls_label_int >= 0:
+        mpls_tags.append({'type': mpls_type, 'label': mpls_label_int, 'tc': mpls_tc_int, 'ttl': mpls_ttl_int})
+    
+    pkt = simple_tcp_packet(dl_dst=dl_dst,
+                            dl_src=dl_src,
+                            mpls_tags=mpls_tags,
+                            ip_src=ip_src,
+                            ip_dst=ip_dst,
+                            ip_tos=ip_tos,  
+                            ip_ttl=ip_ttl,
+                            tcp_sport=tcp_sport,
+                            tcp_dport=tcp_dport)
+    return pkt
+    
+def flow_match_test_port_pair_mpls(parent, ing_port, egr_port, wildcards=0,
+                                   mpls_type=0x8847,
+                                   mpls_label=-1, mpls_tc=0,mpls_ttl=64,
+                                   mpls_label_int=-1, mpls_tc_int=0,
+                                   mpls_ttl_int=32,
+                                   ip_ttl=192,
+                                   exp_mpls_type=0x8847,
+                                   exp_mpls_label=-1, exp_mpls_tc=0,
+                                   exp_mpls_ttl=64,
+                                   exp_mpls_ttl_int=32,
+                                   exp_ip_ttl=192,
+                                   label_match=0, tc_match=0,
+                                   dl_type_match=ETHERTYPE_MPLS,
+                                   match_exp=True,
+                                   add_tag_exp=False,
+                                   exp_msg=ofp.OFPT_FLOW_REMOVED,
+                                   exp_msg_type=0, exp_msg_code=0,
+                                   pkt=None,
+                                   exp_pkt=None, action_list=None,
+                                   check_expire=False):
+    """
+    Flow match test on single packet w/ MPLS tags
+
+    Run test with packet through switch from ing_port to egr_port
+    See flow_match_test for parameter descriptions
+    """
+    logging.info("Pkt match test: " + str(ing_port) + " to " + str(egr_port))
+    logging.debug("  WC: " + hex(wildcards) + " MPLS: " +
+                    str(mpls_label) + " expire: " + str(check_expire))
+
+    if pkt is None:
+
+        pkt = simple_tcp_packet_w_mpls(mpls_type=mpls_type,
+                                       mpls_label=mpls_label,
+                                       mpls_tc=mpls_tc,
+                                       mpls_ttl=mpls_ttl,
+                                       mpls_label_int=mpls_label_int,
+                                       mpls_tc_int=mpls_tc_int,
+                                       mpls_ttl_int=mpls_ttl_int,
+                                       ip_ttl=ip_ttl)
+
+    if exp_pkt is None:
+        if add_tag_exp:
+            exp_pkt = simple_tcp_packet_w_mpls(
+                                           mpls_type=exp_mpls_type,
+                                           mpls_label_ext=exp_mpls_label,
+                                           mpls_tc_ext=exp_mpls_tc,
+                                           mpls_ttl_ext=exp_mpls_ttl,
+                                           mpls_label=mpls_label,
+                                           mpls_tc=mpls_tc,
+                                           mpls_ttl=mpls_ttl,
+                                           mpls_label_int=mpls_label_int,
+                                           mpls_tc_int=mpls_tc_int,
+                                           mpls_ttl_int=exp_mpls_ttl_int,
+                                           ip_ttl=exp_ip_ttl)
+        else:
+            if (exp_mpls_label < 0) and (mpls_label_int >= 0):
+                exp_pkt = simple_tcp_packet_w_mpls(
+                                           mpls_type=mpls_type,
+                                           mpls_label=mpls_label_int,
+                                           mpls_tc=mpls_tc_int,
+                                           mpls_ttl=exp_mpls_ttl_int,
+                                           ip_ttl=exp_ip_ttl)
+            else:
+                exp_pkt = simple_tcp_packet_w_mpls(
+                                           mpls_type=exp_mpls_type,
+                                           mpls_label=exp_mpls_label,
+                                           mpls_tc=exp_mpls_tc,
+                                           mpls_ttl=exp_mpls_ttl,
+                                           mpls_label_int=mpls_label_int,
+                                           mpls_tc_int=mpls_tc_int,
+                                           mpls_ttl_int=exp_mpls_ttl_int,
+                                           ip_ttl=exp_ip_ttl)
+    wildcards = (ofp.OFPFW_ALL & ~(ofp.OFPFW_DL_TYPE | ofp.OFPFW_MPLS_LABEL | ofp.OFPFW_MPLS_TC)) | wildcards
+
+    match = parse.packet_to_flow_match(pkt)
+    parent.assertTrue(match is not None, "Flow match from pkt failed")
+
+    match.mpls_label = label_match
+    match.mpls_tc = tc_match
+    match.wildcards = wildcards
+
+    match.dl_type = dl_type_match
+    match.nw_tos = 0
+    match.nw_proto = 0
+    match.nw_src = 0
+    match.nw_src_mask = 0xFFFFFFFF
+    match.nw_dst = 0
+    match.nw_dst_mask = 0xFFFFFFFF
+    match.tp_src = 0
+    match.tp_dst = 0
+
+    request = flow_msg_create(parent, pkt, ing_port=ing_port,
+                              wildcards=wildcards,
+                              match=match,
+                              egr_port=egr_port,
+                              action_list=action_list)
+
+    flow_msg_install(parent, request)
+
+    logging.debug("Send packet: " + str(ing_port) + " to " + str(egr_port))
+    #logging.debug(str(pkt).encode("hex"))
+    parent.dataplane.send(ing_port, str(pkt))
+
+    if match_exp:
+        receive_pkt_verify(parent, egr_port, exp_pkt)
+        if check_expire:
+            #@todo Not all HW supports both pkt and byte counters
+            flow_removed_verify(parent, request, pkt_count=1, byte_count=len(pkt))
+    else:
+        if exp_msg == ofp.OFPT_FLOW_REMOVED:
+            if check_expire:
+                flow_removed_verify(parent, request, pkt_count=0, byte_count=0)
+        elif exp_msg == ofp.OFPT_ERROR:
+            error_verify(parent, exp_msg_type, exp_msg_code)
+        else:
+            parent.assertTrue(0, "Rcv: Unexpected ofp.message: " + str(exp_msg))
+        (_, rcv_pkt, _) = parent.dataplane.poll(timeout=1)
+        parent.assertFalse(rcv_pkt is not None, "Packet on dataplane")
+
+def flow_match_test_mpls(parent, port_map, wildcards=0,
+                         mpls_type=0x8847,
+                         mpls_label=-1, mpls_tc=0, mpls_ttl=64,
+                         mpls_label_int=-1, mpls_tc_int=0, mpls_ttl_int=32,
+                         ip_ttl = 192,
+                         label_match=0, tc_match=0,
+                         dl_type_match=ETHERTYPE_MPLS,
+                         exp_mpls_type=0x8847,
+                         exp_mpls_label=-1, exp_mpls_tc=0, exp_mpls_ttl=64,
+                         exp_mpls_ttl_int=32,
+                         exp_ip_ttl=192,
+                         match_exp=True,
+                         add_tag_exp=False,
+                         exp_msg=ofp.OFPT_FLOW_REMOVED,
+                         exp_msg_type=0, exp_msg_code=0,
+                         pkt=None,
+                         exp_pkt=None, action_list=None, check_expire=False,
+                         max_test=0):
+    """
+    Run flow_match_test_port_pair on all port pairs
+
+    @param max_test If > 0 no more than this number of tests are executed.
+    @param parent Must implement controller, dataplane, assertTrue, assertEqual
+    and logger
+    @param wildcards For flow match entry
+    @param mpls_type MPLS type
+    @param mpls_label If not -1 create a pkt w/ MPLS tag
+    @param mpls_tc MPLS TC associated with MPLS label
+    @param mpls_ttl MPLS TTL associated with MPLS label
+    @param mpls_label_int If not -1 create a pkt w/ Inner MPLS tag
+    @param mpls_tc_int MPLS TC associated with Inner MPLS label
+    @param mpls_ttl_int MPLS TTL associated with Inner MPLS label
+    @param ip_ttl IP TTL
+    @param label_match Matching value for MPLS LABEL field
+    @param tc_match Matching value for MPLS TC field
+    @param exp_mpls_label Expected MPLS LABEL value. If -1, no MPLS expected
+    @param exp_mpls_tc Expected MPLS TC value
+    @param exp_mpls_ttl Expected MPLS TTL value
+    @param exp_mpls_ttl_int Expected Inner MPLS TTL value
+    @param ip_ttl Expected IP TTL
+    @param match_exp Set whether packet is expected to receive
+    @param add_tag_exp If True, expected_packet has an additional MPLS shim,
+    If not expected_packet's MPLS shim is replaced as specified
+    @param exp_msg Expected ofp.message
+    @param exp_msg_type Expected ofp.message type associated with the ofp.message
+    @param exp_msg_code Expected ofp.message code associated with the msg_type
+    @param pkt If not None, use this packet for ingress
+    @param exp_pkt If not None, use this as the expected output pkt; els use pkt
+    @param action_list Additional actions to add to flow mod
+    @param check_expire Check for flow expiration ofp.message
+    """
+    of_ports = port_map.keys()
+    of_ports.sort()
+    parent.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+    test_count = 0
+
+    for ing_idx in range(len(of_ports)):
+        ingress_port = of_ports[ing_idx]
+        for egr_idx in range(len(of_ports)):
+            if egr_idx == ing_idx:
+                continue
+            egress_port = of_ports[egr_idx]
+            flow_match_test_port_pair_mpls(parent, ingress_port, egress_port,
+                                      wildcards=wildcards,
+                                      mpls_type=mpls_type,
+                                      mpls_label=mpls_label,
+                                      mpls_tc=mpls_tc,
+                                      mpls_ttl=mpls_ttl,
+                                      mpls_label_int=mpls_label_int,
+                                      mpls_tc_int=mpls_tc_int,
+                                      mpls_ttl_int=mpls_ttl_int,
+                                      ip_ttl=ip_ttl,
+                                      label_match=label_match,
+                                      tc_match=tc_match,
+                                      dl_type_match=dl_type_match,
+                                      exp_mpls_type=exp_mpls_type,
+                                      exp_mpls_label=exp_mpls_label,
+                                      exp_mpls_tc=exp_mpls_tc,
+                                      exp_mpls_ttl=exp_mpls_ttl,
+                                      exp_mpls_ttl_int=exp_mpls_ttl_int,
+                                      exp_ip_ttl=exp_ip_ttl,
+                                      match_exp=match_exp,
+                                      exp_msg=exp_msg,
+                                      exp_msg_type=exp_msg_type,
+                                      exp_msg_code=exp_msg_code,
+                                      add_tag_exp=add_tag_exp,
+                                      pkt=pkt, exp_pkt=exp_pkt,
+                                      action_list=action_list,
+                                      check_expire=check_expire)
+            test_count += 1
+            if (max_test > 0) and (test_count >= max_test):
+                logging.info("Ran " + str(test_count) + " tests; exiting")
+                return
+
+def flow_stats_get(parent, match_fields = None):
+    """ Get the flow_stats from the switch
+    Test the response to make sure it's really a flow_stats object
+    """
+    request = ofp.message.flow_stats_request()
+    request.out_port = ofp.OFPP_ANY
+    request.out_group = ofp.OFPG_ANY
+    request.table_id = 0xff
+    if match_fields != None:
+        request.match_fields = match_fields
+    response, _ = parent.controller.transact(request, timeout=2)
+    parent.assertTrue(response is not None, "Did not get response")
+    parent.assertTrue(isinstance(response,ofp.message.flow_stats_reply),
+                      "Expected a flow_stats_reply, but didn't get it")
+    return response
diff --git a/Fabric/Utilities/src/python/oftest/ofutils.py b/Fabric/Utilities/src/python/oftest/ofutils.py
new file mode 100644
index 0000000..7e6044d
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/ofutils.py
@@ -0,0 +1,80 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+
+"""
+Utilities for the OpenFlow test framework
+"""
+
+import random
+import time
+import os
+import fcntl
+import logging
+
+default_timeout = None # set by oft
+default_negative_timeout = None # set by oft
+
+def gen_xid():
+    return random.randrange(1,0xffffffff)
+
+"""
+Wait on a condition variable until the given function returns non-None or a timeout expires.
+The condition variable must already be acquired.
+The timeout value -1 means use the default timeout.
+There is deliberately no support for an infinite timeout.
+"""
+def timed_wait(cv, fn, timeout=-1):
+    if timeout == -1:
+        timeout = default_timeout
+
+    end_time = time.time() + timeout
+    while True:
+        val = fn()
+        if val != None:
+            return val
+
+        remaining_time = end_time - time.time()
+        cv.wait(remaining_time)
+
+        if time.time() > end_time:
+            return None
+
+class EventDescriptor():
+    """
+    Similar to a condition variable, but can be passed to select().
+    Only supports one waiter.
+    """
+
+    def __init__(self):
+        self.pipe_rd, self.pipe_wr = os.pipe()
+        fcntl.fcntl(self.pipe_wr, fcntl.F_SETFL, os.O_NONBLOCK)
+
+    def __del__(self):
+        os.close(self.pipe_rd)
+        os.close(self.pipe_wr)
+
+    def notify(self):
+        try:
+            os.write(self.pipe_wr, "x")
+        except OSError as e:
+            logging.warn("Failed to notify EventDescriptor: %s", e)
+
+    def wait(self):
+        os.read(self.pipe_rd, 1)
+
+    def fileno(self):
+        return self.pipe_rd
diff --git a/Fabric/Utilities/src/python/oftest/packet.py b/Fabric/Utilities/src/python/oftest/packet.py
new file mode 100755
index 0000000..fa887bc
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/packet.py
@@ -0,0 +1,82 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Distributed under the OpenFlow Software License (see LICENSE)
+# Copyright (c) 2010 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+"""
+Wrap scapy to satisfy pylint
+"""
+from oftest import config
+import sys
+
+try:
+    import scapy.config
+    import scapy.route
+    import scapy.layers.l2
+    import scapy.layers.inet
+    if not config["disable_ipv6"]:
+        import scapy.route6
+        import scapy.layers.inet6
+except ImportError:
+    sys.exit("Need to install scapy for packet parsing")
+
+Ether = scapy.layers.l2.Ether
+LLC = scapy.layers.l2.LLC
+SNAP = scapy.layers.l2.SNAP
+Dot1Q = scapy.layers.l2.Dot1Q
+IP = scapy.layers.inet.IP
+IPOption = scapy.layers.inet.IPOption
+ARP = scapy.layers.inet.ARP
+TCP = scapy.layers.inet.TCP
+UDP = scapy.layers.inet.UDP
+ICMP = scapy.layers.inet.ICMP
+
+
+from scapy.fields import *
+from scapy.packet import *
+
+class ThreeBytesField(X3BytesField, ByteField):
+    def i2repr(self, pkt, x):
+        return ByteField.i2repr(self, pkt, x)
+
+class VXLAN(Packet):
+    name = "VXLAN"
+    fields_desc = [ FlagsField("flags", 0x08, 8, ['R', 'R', 'R', 'I', 'R', 'R', 'R', 'R']),
+                    X3BytesField("reserved1", 0x000000),
+                    ThreeBytesField("vni", 0),
+                    XByteField("reserved2", 0x00)]
+
+    def mysummary(self):
+        return self.sprintf("VXLAN (vni=%VXLAN.vni%)")
+
+bind_layers(UDP, VXLAN, dport=4789)
+bind_layers(VXLAN, Ether)
+
+
+class MPLS(Packet): 
+   name = "MPLS" 
+   fields_desc =  [ BitField("label", 3, 20), 
+                    BitField("cos", 0, 3), 
+                    BitField("s", 1, 1), 
+                    ByteField("ttl", 0)  ] 
+
+bind_layers(Ether, MPLS, type=0x8847)
+
+if not config["disable_ipv6"]:
+    IPv6 = scapy.layers.inet6.IPv6
+    ICMPv6Unknown = scapy.layers.inet6.ICMPv6Unknown
+    ICMPv6EchoRequest = scapy.layers.inet6.ICMPv6EchoRequest
diff --git a/Fabric/Utilities/src/python/oftest/parse.py b/Fabric/Utilities/src/python/oftest/parse.py
new file mode 100644
index 0000000..1f94c45
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/parse.py
@@ -0,0 +1,301 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Utility parsing functions
+"""
+
+import sys
+import socket
+import packet as scapy
+
+def parse_mac(mac_str):
+    """
+    Parse a MAC address
+
+    Parse a MAC address ':' separated string of hex digits to an
+    array of integer values.  '00:d0:05:5d:24:00' => [0, 208, 5, 93, 36, 0]
+    @param mac_str The string to convert
+    @return Array of 6 integer values
+    """
+    return map(lambda val: int(val, 16), mac_str.split(":"))
+
+def parse_ip(ip_str):
+    """
+    Parse an IP address
+
+    Parse an IP address '.' separated string of decimal digits to an
+    host ordered integer.  '172.24.74.77' => 
+    @param ip_str The string to convert
+    @return Integer value
+    """
+    array = map(lambda val: int(val), ip_str.split("."))
+    val = 0
+    for a in array:
+        val <<= 8
+        val += a
+    return val
+
+def parse_ipv6(ip_str):
+    """
+    Parse an IPv6 address
+
+    Parse a textual IPv6 address and return a 16 byte binary string.
+    """
+    return socket.inet_pton(socket.AF_INET6, ip_str)
+
+def packet_type_classify(ether):
+    try:
+        dot1q = ether[scapy.Dot1Q]
+    except:
+        dot1q = None
+
+    try:
+        ip = ether[scapy.IP]
+    except:
+        ip = None
+
+    try:
+        tcp = ether[scapy.TCP]
+    except:
+        tcp = None
+
+    try:
+        udp = ether[scapy.UDP]
+    except:
+        udp = None
+
+    try:
+        icmp = ether[scapy.ICMP]
+    except:
+        icmp = None
+
+    try:
+        arp = ether[scapy.ARP]
+    except:
+        arp = None
+    return (dot1q, ip, tcp, udp, icmp, arp)
+
+def packet_to_flow_match(packet):
+    """
+    Create a flow match that matches packet with the given wildcards
+
+    @param packet The packet to use as a flow template
+    @return An loxi.of10.match object
+
+    @todo check min length of packet
+    """
+    import ofp
+    if ofp.OFP_VERSION == 1:
+        return packet_to_flow_match_v1(packet)
+    elif ofp.OFP_VERSION == 3:
+        return packet_to_flow_match_v3(packet)
+    elif ofp.OFP_VERSION == 4:
+        return packet_to_flow_match_v4(packet)
+    elif ofp.OFP_VERSION == 5:
+        return packet_to_flow_match_v5(packet)
+    else:
+        raise NotImplementedError()
+
+def packet_to_flow_match_v1(packet):
+    """
+    OpenFlow 1.0 implementation of packet_to_flow_match
+    """
+    import loxi.of10 as ofp
+
+    if type(packet) == type(""):
+        ether = scapy.Ether(packet)
+    else:
+        ether = packet
+
+    # For now, assume ether IP packet and ignore wildcards
+    try:
+        (dot1q, ip, tcp, udp, icmp, arp) = packet_type_classify(ether)
+    except:
+        raise ValueError("could not classify packet")
+
+    match = ofp.match()
+    match.wildcards = ofp.OFPFW_ALL
+    #@todo Check if packet is other than L2 format
+    match.eth_dst = parse_mac(ether.dst)
+    match.wildcards &= ~ofp.OFPFW_DL_DST
+    match.eth_src = parse_mac(ether.src)
+    match.wildcards &= ~ofp.OFPFW_DL_SRC
+    match.eth_type = ether.type
+    match.wildcards &= ~ofp.OFPFW_DL_TYPE
+
+    if dot1q:
+        match.vlan_vid = dot1q.vlan
+        match.vlan_pcp = dot1q.prio
+        match.eth_type = dot1q.type
+    else:
+        match.vlan_vid = ofp.OFP_VLAN_NONE
+        match.vlan_pcp = 0
+    match.wildcards &= ~ofp.OFPFW_DL_VLAN
+    match.wildcards &= ~ofp.OFPFW_DL_VLAN_PCP
+
+    if ip:
+        match.ipv4_src = parse_ip(ip.src)
+        match.wildcards &= ~ofp.OFPFW_NW_SRC_MASK
+        match.ipv4_dst = parse_ip(ip.dst)
+        match.wildcards &= ~ofp.OFPFW_NW_DST_MASK
+        match.ip_dscp = ip.tos
+        match.wildcards &= ~ofp.OFPFW_NW_TOS
+
+    if tcp:
+        match.ip_proto = 6
+        match.wildcards &= ~ofp.OFPFW_NW_PROTO
+    elif not tcp and udp:
+        tcp = udp
+        match.ip_proto = 17
+        match.wildcards &= ~ofp.OFPFW_NW_PROTO
+
+    if tcp:
+        match.tcp_src = tcp.sport
+        match.wildcards &= ~ofp.OFPFW_TP_SRC
+        match.tcp_dst = tcp.dport
+        match.wildcards &= ~ofp.OFPFW_TP_DST
+
+    if icmp:
+        match.ip_proto = 1
+        match.tcp_src = icmp.type
+        match.tcp_dst = icmp.code
+        match.wildcards &= ~ofp.OFPFW_NW_PROTO
+
+    if arp:
+        match.ip_proto = arp.op
+        match.wildcards &= ~ofp.OFPFW_NW_PROTO
+        match.ipv4_src = parse_ip(arp.psrc)
+        match.wildcards &= ~ofp.OFPFW_NW_SRC_MASK
+        match.ipv4_dst = parse_ip(arp.pdst)
+        match.wildcards &= ~ofp.OFPFW_NW_DST_MASK
+
+    return match
+
+def packet_to_flow_match_v3(packet):
+    """
+    OpenFlow 1.2 implementation of packet_to_flow_match
+    """
+    import loxi.of12 as ofp
+    return packet_to_flow_match_oxm(packet, ofp)
+
+def packet_to_flow_match_v4(packet):
+    """
+    OpenFlow 1.3 implementation of packet_to_flow_match
+    """
+    import loxi.of13 as ofp
+    return packet_to_flow_match_oxm(packet, ofp)
+
+def packet_to_flow_match_v5(packet):
+    """
+    OpenFlow 1.3 implementation of packet_to_flow_match
+    """
+    import loxi.of14 as ofp
+    return packet_to_flow_match_oxm(packet, ofp)
+
+def packet_to_flow_match_oxm(packet, ofp):
+    def parse_ether_layer(layer, match):
+        assert(type(layer) == scapy.Ether)
+        match.oxm_list.append(ofp.oxm.eth_dst(parse_mac(layer.dst)))
+        match.oxm_list.append(ofp.oxm.eth_src(parse_mac(layer.src)))
+
+        if type(layer.payload) == scapy.Dot1Q:
+            layer = layer.payload
+            match.oxm_list.append(ofp.oxm.eth_type(layer.type))
+            match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|layer.vlan))
+            match.oxm_list.append(ofp.oxm.vlan_pcp(layer.prio))
+        else:
+            match.oxm_list.append(ofp.oxm.eth_type(layer.type))
+            match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE))
+
+        if type(layer.payload) == scapy.IP:
+            parse_ipv4_layer(layer.payload, match)
+        elif type(layer.payload) == scapy.IPv6:
+            parse_ipv6_layer(layer.payload, match)
+        elif type(layer.payload) == scapy.ARP:
+            parse_arp_layer(layer.payload, match)
+        # TODO MPLS
+
+    def parse_ipv4_layer(layer, match):
+        assert(type(layer) == scapy.IP)
+        match.oxm_list.append(ofp.oxm.ip_proto(layer.proto))
+        match.oxm_list.append(ofp.oxm.ip_dscp(layer.tos >> 2))
+        match.oxm_list.append(ofp.oxm.ip_ecn(layer.tos & 3))
+        match.oxm_list.append(ofp.oxm.ipv4_src(parse_ip(layer.src)))
+        match.oxm_list.append(ofp.oxm.ipv4_dst(parse_ip(layer.dst)))
+
+        if type(layer.payload) == scapy.TCP:
+            parse_tcp_layer(layer.payload, match)
+        elif type(layer.payload) == scapy.UDP:
+            parse_udp_layer(layer.payload, match)
+        elif type(layer.payload) == scapy.ICMP:
+            parse_icmpv4_layer(layer.payload, match)
+        # TODO SCTP
+
+    def parse_tcp_layer(layer, match):
+        assert(type(layer) == scapy.TCP)
+        match.oxm_list.append(ofp.oxm.tcp_src(layer.sport))
+        match.oxm_list.append(ofp.oxm.tcp_dst(layer.dport))
+
+    def parse_udp_layer(layer, match):
+        assert(type(layer) == scapy.UDP)
+        match.oxm_list.append(ofp.oxm.udp_src(layer.sport))
+        match.oxm_list.append(ofp.oxm.udp_dst(layer.dport))
+
+    def parse_icmpv4_layer(layer, match):
+        assert(type(layer) == scapy.ICMP)
+        match.oxm_list.append(ofp.oxm.icmpv4_type(layer.type))
+        match.oxm_list.append(ofp.oxm.icmpv4_code(layer.code))
+
+    def parse_arp_layer(layer, match):
+        assert(type(layer) == scapy.ARP)
+        match.oxm_list.append(ofp.oxm.arp_op(layer.op))
+        match.oxm_list.append(ofp.oxm.arp_spa(parse_ip(layer.psrc)))
+        match.oxm_list.append(ofp.oxm.arp_tpa(parse_ip(layer.pdst)))
+        match.oxm_list.append(ofp.oxm.arp_sha(parse_mac(layer.hwsrc)))
+        match.oxm_list.append(ofp.oxm.arp_tha(parse_mac(layer.hwdst)))
+
+    def parse_ipv6_layer(layer, match):
+        assert(type(layer) == scapy.IPv6)
+        # TODO handle chained headers
+        match.oxm_list.append(ofp.oxm.ip_proto(layer.nh))
+        match.oxm_list.append(ofp.oxm.ip_dscp(layer.tc >> 2))
+        match.oxm_list.append(ofp.oxm.ip_ecn(layer.tc & 3))
+        match.oxm_list.append(ofp.oxm.ipv6_src(parse_ipv6(layer.src)))
+        match.oxm_list.append(ofp.oxm.ipv6_dst(parse_ipv6(layer.dst)))
+        match.oxm_list.append(ofp.oxm.ipv6_flabel(layer.fl))
+
+        if type(layer.payload) == scapy.TCP:
+            parse_tcp_layer(layer.payload, match)
+        elif type(layer.payload) == scapy.UDP:
+            parse_udp_layer(layer.payload, match)
+        elif layer.nh == 0x3a:
+            parse_icmpv6_layer(layer.payload, match)
+        # TODO ND
+        # TODO SCTP
+
+    def parse_icmpv6_layer(layer, match):
+        match.oxm_list.append(ofp.oxm.icmpv6_type(layer.type))
+        match.oxm_list.append(ofp.oxm.icmpv6_code(layer.code))
+
+    if type(packet) == type(""):
+        ether = scapy.Ether(packet)
+    else:
+        ether = packet
+
+    match = ofp.match()
+    parse_ether_layer(packet, match)
+    return match
diff --git a/Fabric/Utilities/src/python/oftest/pcap_writer.py b/Fabric/Utilities/src/python/oftest/pcap_writer.py
new file mode 100644
index 0000000..b405033
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/pcap_writer.py
@@ -0,0 +1,77 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Pcap file writer
+"""
+
+import struct
+
+PcapHeader = struct.Struct("<LHHLLLL")
+PcapPktHeader = struct.Struct("<LLLL")
+PPIPktHeader = struct.Struct("<BBHL")
+PPIAggregateField = struct.Struct("<HHL")
+
+class PcapWriter(object):
+    def __init__(self, filename):
+        """
+        Open a pcap file
+        """
+        self.stream = file(filename, 'w')
+
+        self.stream.write(PcapHeader.pack(
+            0xa1b2c3d4, # magic
+            2, # major
+            4, # minor
+            0, # timezone offset
+            0, # timezone accuracy
+            65535, # snapshot length
+            192 # PPI linktype
+        ))
+
+    def write(self, data, timestamp, port):
+        """
+        Write a packet to a pcap file
+
+        'data' should be a string containing the packet data.
+        'timestamp' should be a float.
+        'port' should be an integer port number.
+        """
+        ppi_len = PPIPktHeader.size + PPIAggregateField.size
+        self.stream.write(PcapPktHeader.pack(
+            int(timestamp), # timestamp seconds
+            int((timestamp - int(timestamp)) * 10**6), # timestamp microseconds
+            len(data) + ppi_len, # truncated length
+            len(data) + ppi_len # un-truncated length
+        ))
+        self.stream.write(PPIPktHeader.pack(
+            0, # version
+            0, # flags
+            ppi_len, # length
+            1, # ethernet dlt
+        ))
+        self.stream.write(PPIAggregateField.pack(8, PPIAggregateField.size - 4, port))
+        self.stream.write(data)
+
+    def close(self):
+        self.stream.close()
+
+if __name__ == "__main__":
+    import time
+    print("Writing test pcap to test.pcap")
+    pcap_writer = PcapWriter("test.pcap")
+    pcap_writer.write("\x00\x01\x02\x03\x04\x05\x00\x0a\x0b\x0c\x0d\x0e\x08\x00", time.time(), 42)
+    pcap_writer.close()
diff --git a/Fabric/Utilities/src/python/oftest/test_parse.py b/Fabric/Utilities/src/python/oftest/test_parse.py
new file mode 100755
index 0000000..d4762ef
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/test_parse.py
@@ -0,0 +1,195 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+#!/usr/bin/env python
+import unittest
+import parse
+import packet as scapy
+
+class TestPacketToFlowMatchV3(unittest.TestCase):
+    def test_tcp(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a')/ \
+            scapy.IP(src='192.168.0.1', dst='192.168.0.2', tos=2 | (32 << 2), ttl=64)/ \
+            scapy.TCP(sport=1234, dport=80)
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x0800),
+            ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE),
+            ofp.oxm.ip_proto(6),
+            ofp.oxm.ip_dscp(32),
+            ofp.oxm.ip_ecn(2),
+            ofp.oxm.ipv4_src(0xc0a80001),
+            ofp.oxm.ipv4_dst(0xc0a80002),
+            ofp.oxm.tcp_src(1234),
+            ofp.oxm.tcp_dst(80)
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+    def test_udp(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a')/ \
+            scapy.IP(src='192.168.0.1', dst='192.168.0.2', tos=2 | (32 << 2), ttl=64)/ \
+            scapy.UDP(sport=1234, dport=80)
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x0800),
+            ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE),
+            ofp.oxm.ip_proto(17),
+            ofp.oxm.ip_dscp(32),
+            ofp.oxm.ip_ecn(2),
+            ofp.oxm.ipv4_src(0xc0a80001),
+            ofp.oxm.ipv4_dst(0xc0a80002),
+            ofp.oxm.udp_src(1234),
+            ofp.oxm.udp_dst(80)
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+    def test_icmp(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a')/ \
+            scapy.IP(src='192.168.0.1', dst='192.168.0.2', tos=2 | (32 << 2), ttl=64)/ \
+            scapy.ICMP(type=8, code=1)
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x0800),
+            ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE),
+            ofp.oxm.ip_proto(1),
+            ofp.oxm.ip_dscp(32),
+            ofp.oxm.ip_ecn(2),
+            ofp.oxm.ipv4_src(0xc0a80001),
+            ofp.oxm.ipv4_dst(0xc0a80002),
+            ofp.oxm.icmpv4_type(8),
+            ofp.oxm.icmpv4_code(1)
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+    def test_arp(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a')/ \
+            scapy.ARP(hwsrc='00:01:02:03:04:05', hwdst='00:06:07:08:09:0a', \
+                      psrc='192.168.0.1', pdst='192.168.0.2', op=1)
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x0806),
+            ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE),
+            ofp.oxm.arp_op(1),
+            ofp.oxm.arp_spa(0xc0a80001),
+            ofp.oxm.arp_tpa(0xc0a80002),
+            ofp.oxm.arp_sha([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.arp_tha([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+    def test_tcpv6(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a')/ \
+            scapy.IPv6(src="::1", dst="::2", nh=6, tc=2 | (32 << 2), fl=7)/ \
+            scapy.TCP(sport=1234, dport=80)
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x86dd),
+            ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE),
+            ofp.oxm.ip_proto(6),
+            ofp.oxm.ip_dscp(32),
+            ofp.oxm.ip_ecn(2),
+            ofp.oxm.ipv6_src("\x00" * 15 + "\x01"),
+            ofp.oxm.ipv6_dst("\x00" * 15 + "\x02"),
+            ofp.oxm.ipv6_flabel(7),
+            ofp.oxm.tcp_src(1234),
+            ofp.oxm.tcp_dst(80)
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+    def test_icmpv6(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a')/ \
+            scapy.IPv6(src="::1", dst="::2", tc=2 | (32 << 2), fl=7)/ \
+            scapy.ICMPv6EchoRequest()
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x86dd),
+            ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE),
+            ofp.oxm.ip_proto(0x3a),
+            ofp.oxm.ip_dscp(32),
+            ofp.oxm.ip_ecn(2),
+            ofp.oxm.ipv6_src("\x00" * 15 + "\x01"),
+            ofp.oxm.ipv6_dst("\x00" * 15 + "\x02"),
+            ofp.oxm.ipv6_flabel(7),
+            ofp.oxm.icmpv6_type(128),
+            ofp.oxm.icmpv6_code(0)
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+    def test_vlan(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a')/ \
+            scapy.Dot1Q(vlan=50, prio=5)/ \
+            scapy.IP(src='192.168.0.1', dst='192.168.0.2', tos=2 | (32 << 2), ttl=64)/ \
+            scapy.TCP(sport=1234, dport=80)
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x0800),
+            ofp.oxm.vlan_vid(50),
+            ofp.oxm.vlan_pcp(5),
+            ofp.oxm.ip_proto(6),
+            ofp.oxm.ip_dscp(32),
+            ofp.oxm.ip_ecn(2),
+            ofp.oxm.ipv4_src(0xc0a80001),
+            ofp.oxm.ipv4_dst(0xc0a80002),
+            ofp.oxm.tcp_src(1234),
+            ofp.oxm.tcp_dst(80)
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+    def test_unknown_ethertype(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a', type=0x0801)/ \
+            ('\x11' * 20)
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x0801),
+            ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE),
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
diff --git a/Fabric/Utilities/src/python/oftest/testutils.py b/Fabric/Utilities/src/python/oftest/testutils.py
new file mode 100755
index 0000000..3a147c7
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/testutils.py
@@ -0,0 +1,2262 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import sys
+import copy
+import logging
+import types
+import time
+import re
+from Queue import Queue
+
+import packet as scapy
+
+import oftest
+import oftest.controller
+import oftest.dataplane
+import oftest.parse
+import oftest.ofutils
+import ofp
+
+global skipped_test_count
+skipped_test_count = 0
+
+_import_blacklist = set(locals().keys())
+
+# Some useful defines
+IP_ETHERTYPE = 0x800
+TCP_PROTOCOL = 0x6
+UDP_PROTOCOL = 0x11
+
+MINSIZE = 0
+
+def delete_all_flows(ctrl, send_barrier=True):
+    """
+    Delete all flows on the switch
+    @param ctrl The controller object for the test
+    @param send_barrier Whether or not to send a barrier message
+    """
+
+    logging.info("Deleting all flows")
+    msg = ofp.message.flow_delete()
+    if ofp.OFP_VERSION in [1, 2]:
+        msg.match.wildcards = ofp.OFPFW_ALL
+        msg.out_port = ofp.OFPP_NONE
+        msg.buffer_id = 0xffffffff
+    elif ofp.OFP_VERSION >= 3:
+        msg.table_id = ofp.OFPTT_ALL
+        msg.buffer_id = ofp.OFP_NO_BUFFER
+        msg.out_port = ofp.OFPP_ANY
+        msg.out_group = ofp.OFPG_ANY
+    ctrl.message_send(msg)
+    if send_barrier:
+        do_barrier(ctrl)
+    return 0 # for backwards compatibility
+
+def delete_all_groups(ctrl):
+    """
+    Delete all groups on the switch
+    @param ctrl The controller object for the test
+    """
+
+    logging.info("Deleting all groups")
+    msg = ofp.message.group_delete(group_id=ofp.OFPG_ALL)
+    ctrl.message_send(msg)
+    do_barrier(ctrl)
+
+def delete_groups(ctrl, group_queue=Queue()):
+    """
+    Delete all groups on list
+    @param ctrl The controller object for the test
+    :param group_queue:
+    """
+    logging.info("Deleting groups")
+    while (not group_queue.empty()):
+        msg = ofp.message.group_delete(group_id=group_queue.get())
+        ctrl.message_send(msg)
+        do_barrier(ctrl)
+
+def delete_group(ctrl, group_id):
+    """
+    Delete a single group
+    @param ctrl The controller object for the test
+    :param group_id
+    """
+    logging.info("Deleting a single group with groupId:" + str(group_id))
+    msg = ofp.message.group_delete(group_id=group_id)
+    ctrl.message_send(msg)
+    do_barrier(ctrl)
+
+def required_wildcards(parent):
+    w = test_param_get('required_wildcards', default='default')
+    if w == 'l3-l4':
+        return (ofp.OFPFW_NW_SRC_ALL | ofp.OFPFW_NW_DST_ALL | ofp.OFPFW_NW_TOS
+                | ofp.OFPFW_NW_PROTO | ofp.OFPFW_TP_SRC | ofp.OFPFW_TP_DST)
+    else:
+        return 0
+
+def simple_packet(content='00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '
+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '
+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '
+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'):
+
+    pkt = ''.join(content.split(" ")).decode('hex')
+    pkt = scapy.Ether(pkt)
+    if len(pkt) < 64:
+        pkt = pkt/("D" * (64 - len(pkt)))
+    #scapy.hexdump(pkt)
+    return pkt
+
+def simple_tcp_packet(pktlen=100,
+                      eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      vlan_vid=0,
+                      outer_vlan=None,
+                      vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      tcp_sport=1234,
+                      tcp_dport=80,
+                      tcp_flags="S",
+                      ip_ihl=None,
+                      ip_options=False
+                      ):
+    """
+    Return a simple dataplane TCP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destinatino MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param ip_ttl IP TTL
+    @param tcp_dport TCP destination port
+    @param tcp_sport TCP source port
+    @param tcp_flags TCP Control flags
+
+    Generates a simple TCP request.  Users
+    shouldn't assume anything about this packet other than that
+    it is a valid ethernet/IP/TCP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    # Note Dot1Q.id is really CFI
+    if (dl_vlan_enable):
+        pkt = scapy.Ether( dst=eth_dst, src=eth_src )
+        if outer_vlan:
+            pkt = pkt/scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=outer_vlan)
+
+        pkt = pkt/scapy.Dot1Q( prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid )/ \
+              scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+              scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+    else:
+        if not ip_options:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+                scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+        else:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl, options=ip_options)/ \
+                scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+
+    pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_tcpv6_packet(pktlen=100,
+                        eth_dst='00:01:02:03:04:05',
+                        eth_src='00:06:07:08:09:0a',
+                        dl_vlan_enable=False,
+                        vlan_vid=0,
+                        vlan_pcp=0,
+                        ipv6_src='2001:db8:85a3::8a2e:370:7334',
+                        ipv6_dst='2001:db8:85a3::8a2e:370:7335',
+                        ipv6_tc=0,
+                        ipv6_hlim=64,
+                        ipv6_fl=0,
+                        tcp_sport=1234,
+                        tcp_dport=80,
+                        tcp_flags="S"):
+    """
+    Return a simple IPv6/TCP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destination MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ipv6_src IPv6 source
+    @param ipv6_dst IPv6 destination
+    @param ipv6_tc IPv6 traffic class
+    @param ipv6_ttl IPv6 hop limit
+    @param ipv6_fl IPv6 flow label
+    @param tcp_dport TCP destination port
+    @param tcp_sport TCP source port
+    @param tcp_flags TCP Control flags
+
+    Generates a simple TCP request. Users shouldn't assume anything about this
+    packet other than that it is a valid ethernet/IPv6/TCP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+    if dl_vlan_enable or vlan_vid or vlan_pcp:
+        pkt /= scapy.Dot1Q(vlan=vlan_vid, prio=vlan_pcp)
+    pkt /= scapy.IPv6(src=ipv6_src, dst=ipv6_dst, fl=ipv6_fl, tc=ipv6_tc, hlim=ipv6_hlim)
+    pkt /= scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+    pkt /= ("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_udp_packet(pktlen=100,
+                      eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      vlan_vid=0,
+                      vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      udp_sport=1234,
+                      udp_dport=80,
+                      ip_ihl=None,
+                      ip_options=False
+                      ):
+    """
+    Return a simple dataplane UDP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destination MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param ip_ttl IP TTL
+    @param udp_dport UDP destination port
+    @param udp_sport UDP source port
+
+    Generates a simple UDP packet. Users shouldn't assume anything about
+    this packet other than that it is a valid ethernet/IP/UDP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    # Note Dot1Q.id is really CFI
+    if (dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)/ \
+            scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            scapy.UDP(sport=udp_sport, dport=udp_dport)
+    else:
+        if not ip_options:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+                scapy.UDP(sport=udp_sport, dport=udp_dport)
+        else:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl, options=ip_options)/ \
+                scapy.UDP(sport=udp_sport, dport=udp_dport)
+
+    pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+
+def simple_tcp_packet_two_vlan(pktlen=100,
+                      eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      out_dl_vlan_enable=False,
+                      in_dl_vlan_enable=False,
+                      out_vlan_vid=0,
+                      out_vlan_pcp=0,
+                      out_vlan_tpid=0x8100,
+                      out_dl_vlan_cfi=0,
+                      in_vlan_vid=0,
+                      in_vlan_pcp=0,
+                      in_dl_vlan_cfi=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      tcp_sport=1234,
+                      tcp_dport=80,
+                      tcp_flags="S",
+                      ip_ihl=None,
+                      ip_options=False
+                      ):
+    """
+    Return a simple dataplane TCP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destinatino MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param ip_ttl IP TTL
+    @param tcp_dport TCP destination port
+    @param tcp_sport TCP source port
+    @param tcp_flags TCP Control flags
+
+    Generates a simple TCP request.  Users
+    shouldn't assume anything about this packet other than that
+    it is a valid ethernet/IP/TCP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    # Note Dot1Q.id is really CFI
+    if (out_dl_vlan_enable and in_dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src, type=out_vlan_tpid)/ \
+            scapy.Dot1Q(prio=out_vlan_pcp, id=out_dl_vlan_cfi, vlan=out_vlan_vid)
+
+        if in_dl_vlan_enable:
+            pkt = pkt/scapy.Dot1Q(prio=in_vlan_pcp, id=in_dl_vlan_cfi, vlan=in_vlan_vid)
+
+        pkt = pkt/scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+    elif (out_dl_vlan_enable and (not in_dl_vlan_enable)):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.Dot1Q(prio=out_vlan_pcp, id=out_dl_vlan_cfi, vlan=out_vlan_vid)/ \
+            scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+    elif ((not out_dl_vlan_enable) and in_dl_vlan_enable):
+        assert(0) #shall not have this caes
+    else:
+        if not ip_options:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+                scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+        else:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl, options=ip_options)/ \
+                scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+
+    pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_vxlan_packet(eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      vlan_vid=0,
+                      vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      udp_sport=1234,
+                      udp_dport=4789,
+                      vnid=1,
+                      inner_payload=None,
+                      ip_ihl=None,
+                      ip_options=False
+                      ):
+    """
+    Return a simple dataplane UDP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destination MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param ip_ttl IP TTL
+    @param udp_dport UDP destination port
+    @param udp_sport UDP source port
+    @param inner_pyload inner pacekt content
+    Generates a simple UDP packet. Users shouldn't assume anything about
+    this packet other than that it is a valid ethernet/IP/UDP frame.
+    """
+
+    # Note Dot1Q.id is really CFI
+    if (dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)/ \
+            scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            scapy.UDP(sport=udp_sport, dport=udp_dport)
+    else:
+        if not ip_options:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+                scapy.UDP(sport=udp_sport, dport=udp_dport)
+        else:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl, options=ip_options)/ \
+                scapy.UDP(sport=udp_sport, dport=udp_dport)
+
+    #add vxlan header
+    pkt = pkt/scapy.VXLAN(vni=vnid)
+    #add innder payload
+    if inner_payload!=None:
+        pkt=pkt/inner_payload
+
+    return pkt
+
+def mpls_packet(pktlen=100,
+                      eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      vlan_vid=0,
+                      vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      tcp_sport=1234,
+                      tcp_dport=80,
+                      tcp_flags="S",
+                      ip_ihl=None,
+                      ip_options=False,
+                      label=None,
+                      inner_payload=True,
+		      encapsulated_ethernet=False,
+		      encapsulated_eth_src='01:02:03:04:05:11',
+		      encapsulated_eth_dst='01:02:03:04:05:22'
+                      ):
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    # Note Dot1Q.id is really CFI
+    if (dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)
+    else:
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+
+    #add MPLS header
+    for i in range(len(label)):
+        l,c,s,t=label[i]
+        pkt = pkt/scapy.MPLS(label=l, cos=c, s=s, ttl=t)
+
+    #add innder payload
+    if inner_payload!=None:
+        if not encapsulated_ethernet:
+        	pkt=pkt / \
+           	   scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            	   scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+        else:
+	       	pkt=pkt / \
+		   scapy.Ether(dst=encapsulated_eth_dst, src=encapsulated_eth_src)/ \
+           	   scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            	   scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+
+    pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def pw_packet(pktlen=100,
+                      out_eth_dst='00:01:02:03:04:05',
+                      out_eth_src='00:06:07:08:09:0a',
+                      label=None,
+                      cw=None,
+                      in_eth_dst='00:01:02:03:04:05',
+                      in_eth_src='00:06:07:08:09:0a',
+                      out_dl_vlan_enable=False,
+                      in_dl_vlan_enable=False,
+                      out_vlan_vid=0,
+                      out_vlan_pcp=0,
+                      out_dl_vlan_cfi=0,
+                      in_vlan_vid=0,
+                      in_vlan_pcp=0,
+                      in_dl_vlan_cfi=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      tcp_sport=1234,
+                      tcp_dport=80,
+                      tcp_flags="S",
+                      ip_ihl=None,
+                      ip_options=False
+                      ):
+    """
+    Return a simple dataplane TCP packet encapsulated
+    in a pw packet
+    """
+
+    # Add the outer ethernet header
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    pkt = scapy.Ether(dst=out_eth_dst, src=out_eth_src)
+
+    #add MPLS header
+    for i in range(len(label)):
+        l,c,s,t=label[i]
+        pkt = pkt/scapy.MPLS(label=l, cos=c, s=s, ttl=t)
+
+    #add the PW CW
+    l,c,s,t=cw
+    pkt = pkt/scapy.MPLS(label=l, cos=c, s=s, ttl=t)
+
+    # Note Dot1Q.id is really CFI
+    if (out_dl_vlan_enable and in_dl_vlan_enable):
+
+        pkt = pkt/scapy.Ether(dst=in_eth_dst, src=in_eth_src)/ \
+            scapy.Dot1Q(prio=out_vlan_pcp, id=out_dl_vlan_cfi, vlan=out_vlan_vid)
+
+        pkt = pkt/scapy.Dot1Q(prio=in_vlan_pcp, id=in_dl_vlan_cfi, vlan=in_vlan_vid)
+
+        pkt = pkt/scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+
+    elif (out_dl_vlan_enable and (not in_dl_vlan_enable)):
+
+        pkt = pkt/scapy.Ether(dst=in_eth_dst, src=in_eth_src)/ \
+            scapy.Dot1Q(prio=out_vlan_pcp, id=out_dl_vlan_cfi, vlan=out_vlan_vid)/ \
+            scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+
+    elif ((not out_dl_vlan_enable) and in_dl_vlan_enable):
+
+        assert(0) #shall not have this caes
+
+    else:
+        if not ip_options:
+            pkt = pkt/scapy.Ether(dst=in_eth_dst, src=in_eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+                scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+        else:
+            pkt = pkt/scapy.Ether(dst=in_eth_dst, src=in_eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl, options=ip_options)/ \
+                scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+
+    pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def mplsv6_packet(pktlen=100,
+                      eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      vlan_vid=0,
+                      vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      ipv6_src='2001:db8:85a3::8a2e:370:7334',
+                      ipv6_dst='2001:db8:85a3::8a2e:370:7335',
+                      ipv6_tc=0,
+                      ipv6_hlim=64,
+                      ipv6_fl=0,
+                      tcp_sport=1234,
+                      tcp_dport=80,
+                      tcp_flags="S",
+                      label=None,
+                      inner_payload=True
+                      ):
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    # Note Dot1Q.id is really CFI
+    if (dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)
+    else:
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+
+    #add MPLS header
+    for i in range(len(label)):
+        l,c,s,t=label[i]
+        pkt = pkt/scapy.MPLS(label=l, cos=c, s=s, ttl=t)
+
+    #add innder payload
+    if inner_payload!=None:
+        pkt=pkt / \
+            scapy.IPv6(src=ipv6_src, dst=ipv6_dst, fl=ipv6_fl, tc=ipv6_tc, hlim=ipv6_hlim)/ \
+            scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+
+    pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_mpls_packet(eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      vlan_vid=0,
+                      vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      label=None,
+                      inner_payload=None
+                      ):
+    """
+    Return a simple dataplane MPLS packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destination MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param inner_pyload inner pacekt content
+    Generates a simple MPLS packet. Users shouldn't assume anything about
+    this packet other than that it is a valid ethernet/IP/UDP frame.
+    """
+
+    # Note Dot1Q.id is really CFI
+    if (dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)
+    else:
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+
+    #add MPLS header
+    for i in range(len(label)):
+        l,c,s,t=label[i]
+        pkt = pkt/scapy.MPLS(label=l, cos=c, s=s, ttl=t)
+
+    #add innder payload
+    if inner_payload!=None:
+        pkt=pkt/inner_payload
+
+    return pkt
+
+def simple_udpv6_packet(pktlen=100,
+                        eth_dst='00:01:02:03:04:05',
+                        eth_src='00:06:07:08:09:0a',
+                        dl_vlan_enable=False,
+                        vlan_vid=0,
+                        vlan_pcp=0,
+                        ipv6_src='2001:db8:85a3::8a2e:370:7334',
+                        ipv6_dst='2001:db8:85a3::8a2e:370:7335',
+                        ipv6_tc=0,
+                        ipv6_hlim=64,
+                        ipv6_fl=0,
+                        udp_sport=1234,
+                        udp_dport=80):
+    """
+    Return a simple IPv6/UDP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destination MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ipv6_src IPv6 source
+    @param ipv6_dst IPv6 destination
+    @param ipv6_tc IPv6 traffic class
+    @param ipv6_ttl IPv6 hop limit
+    @param ipv6_fl IPv6 flow label
+    @param udp_dport UDP destination port
+    @param udp_sport UDP source port
+
+    Generates a simple UDP request. Users shouldn't assume anything about this
+    packet other than that it is a valid ethernet/IPv6/UDP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+    if dl_vlan_enable or vlan_vid or vlan_pcp:
+        pkt /= scapy.Dot1Q(vlan=vlan_vid, prio=vlan_pcp)
+    pkt /= scapy.IPv6(src=ipv6_src, dst=ipv6_dst, fl=ipv6_fl, tc=ipv6_tc, hlim=ipv6_hlim)
+    pkt /= scapy.UDP(sport=udp_sport, dport=udp_dport)
+    pkt /= ("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_icmp_packet(pktlen=60,
+                      eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      vlan_vid=0,
+                      vlan_pcp=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      ip_id=1,
+                      icmp_type=8,
+                      icmp_code=0,
+                      icmp_data=''):
+    """
+    Return a simple ICMP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destinatino MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param ip_ttl IP TTL
+    @param ip_id IP Identification
+    @param icmp_type ICMP type
+    @param icmp_code ICMP code
+    @param icmp_data ICMP data
+
+    Generates a simple ICMP ECHO REQUEST.  Users
+    shouldn't assume anything about this packet other than that
+    it is a valid ethernet/ICMP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    if (dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.Dot1Q(prio=vlan_pcp, id=0, vlan=vlan_vid)/ \
+            scapy.IP(src=ip_src, dst=ip_dst, ttl=ip_ttl, tos=ip_tos, id=ip_id)/ \
+            scapy.ICMP(type=icmp_type, code=icmp_code)/ icmp_data
+    else:
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.IP(src=ip_src, dst=ip_dst, ttl=ip_ttl, tos=ip_tos, id=ip_id)/ \
+            scapy.ICMP(type=icmp_type, code=icmp_code)/ icmp_data
+
+    pkt = pkt/("0" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_icmpv6_packet(pktlen=100,
+                         eth_dst='00:01:02:03:04:05',
+                         eth_src='00:06:07:08:09:0a',
+                         dl_vlan_enable=False,
+                         vlan_vid=0,
+                         vlan_pcp=0,
+                         ipv6_src='2001:db8:85a3::8a2e:370:7334',
+                         ipv6_dst='2001:db8:85a3::8a2e:370:7335',
+                         ipv6_tc=0,
+                         ipv6_hlim=64,
+                         ipv6_fl=0,
+                         icmp_type=8,
+                         icmp_code=0):
+    """
+    Return a simple ICMPv6 packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destination MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ipv6_src IPv6 source
+    @param ipv6_dst IPv6 destination
+    @param ipv6_tc IPv6 traffic class
+    @param ipv6_ttl IPv6 hop limit
+    @param ipv6_fl IPv6 flow label
+    @param icmp_type ICMP type
+    @param icmp_code ICMP code
+
+    Generates a simple ICMP ECHO REQUEST. Users shouldn't assume anything
+    about this packet other than that it is a valid ethernet/IPv6/ICMP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+    if dl_vlan_enable or vlan_vid or vlan_pcp:
+        pkt /= scapy.Dot1Q(vlan=vlan_vid, prio=vlan_pcp)
+    pkt /= scapy.IPv6(src=ipv6_src, dst=ipv6_dst, fl=ipv6_fl, tc=ipv6_tc, hlim=ipv6_hlim)
+    pkt /= scapy.ICMPv6Unknown(type=icmp_type, code=icmp_code)
+    pkt /= ("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_arp_packet(pktlen=60,
+                      eth_dst='ff:ff:ff:ff:ff:ff',
+                      eth_src='00:06:07:08:09:0a',
+                      vlan_vid=0,
+                      vlan_pcp=0,
+                      arp_op=1,
+                      ip_snd='192.168.0.1',
+                      ip_tgt='192.168.0.2',
+                      hw_snd='00:06:07:08:09:0a',
+                      hw_tgt='00:00:00:00:00:00',
+                      ):
+    """
+    Return a simple ARP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destinatino MAC
+    @param eth_src Source MAC
+    @param arp_op Operation (1=request, 2=reply)
+    @param ip_snd Sender IP
+    @param ip_tgt Target IP
+    @param hw_snd Sender hardware address
+    @param hw_tgt Target hardware address
+
+    Generates a simple ARP REQUEST.  Users
+    shouldn't assume anything about this packet other than that
+    it is a valid ethernet/ARP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+    if vlan_vid or vlan_pcp:
+        pkt /= scapy.Dot1Q(vlan=vlan_vid, prio=vlan_pcp)
+    pkt /= scapy.ARP(hwsrc=hw_snd, hwdst=hw_tgt, pdst=ip_tgt, psrc=ip_snd, op=arp_op)
+
+    pkt = pkt/("\0" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_eth_packet(pktlen=60,
+                      eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      eth_type=0x88cc):
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    pkt = scapy.Ether(dst=eth_dst, src=eth_src, type=eth_type)
+
+    pkt = pkt/("0" * (pktlen - len(pkt)))
+
+    return pkt
+
+def qinq_tcp_packet(pktlen=100,
+                    eth_dst='00:01:02:03:04:05',
+                    eth_src='00:06:07:08:09:0a',
+                    dl_vlan_outer=20,
+                    dl_vlan_pcp_outer=0,
+                    dl_vlan_cfi_outer=0,
+                    vlan_vid=10,
+                    vlan_pcp=0,
+                    dl_vlan_cfi=0,
+                    ip_src='192.168.0.1',
+                    ip_dst='192.168.0.2',
+                    ip_tos=0,
+                    ip_ttl=64,
+                    tcp_sport=1234,
+                    tcp_dport=80,
+                    ip_ihl=None,
+                    ip_options=False
+                    ):
+    """
+    Return a doubly tagged dataplane TCP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destinatino MAC
+    @param eth_src Source MAC
+    @param dl_vlan_outer Outer VLAN ID
+    @param dl_vlan_pcp_outer Outer VLAN priority
+    @param dl_vlan_cfi_outer Outer VLAN cfi bit
+    @param vlan_vid Inner VLAN ID
+    @param vlan_pcp VLAN priority
+    @param dl_vlan_cfi VLAN cfi bit
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param tcp_dport TCP destination port
+    @param ip_sport TCP source port
+
+    Generates a TCP request.  Users
+    shouldn't assume anything about this packet other than that
+    it is a valid ethernet/IP/TCP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    # Note Dot1Q.id is really CFI
+    pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+          scapy.Dot1Q(prio=dl_vlan_pcp_outer, id=dl_vlan_cfi_outer, vlan=dl_vlan_outer)/ \
+          scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)/ \
+          scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+          scapy.TCP(sport=tcp_sport, dport=tcp_dport)
+
+    pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def qinq_packet(pktlen=100,
+                type=0x0800,
+                eth_dst='00:01:02:03:04:05',
+                eth_src='00:06:07:08:09:0a',
+                dl_vlan_outer=20,
+                dl_vlan_pcp_outer=0,
+                dl_vlan_cfi_outer=0,
+                vlan_vid=10,
+                vlan_pcp=0,
+                dl_vlan_cfi=0,
+                ):
+    """
+    Return a doubly tagged dataplane qinq packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param type ethernet type
+    @param eth_dst Destinatino MAC
+    @param eth_src Source MAC
+    @param dl_vlan_outer Outer VLAN ID
+    @param dl_vlan_pcp_outer Outer VLAN priority
+    @param dl_vlan_cfi_outer Outer VLAN cfi bit
+    @param vlan_vid Inner VLAN ID
+    @param vlan_pcp VLAN priority
+    @param dl_vlan_cfi VLAN cfi bit
+
+    Generates a qinq request.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    # Note Dot1Q.id is really CFI
+    pkt = scapy.Ether(dst=eth_dst, src=eth_src, type=type) / \
+          scapy.Dot1Q(prio=dl_vlan_pcp_outer, id=dl_vlan_cfi_outer, vlan=dl_vlan_outer) / \
+          scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid) / \
+          scapy.IP()
+
+    pkt = pkt / ("D" * (pktlen - len(pkt)))
+    return pkt
+
+def simple_ether_packet_two_vlan(pktlen=100,
+                                 eth_dst='00:01:02:03:04:05',
+                                 eth_src='00:06:07:08:09:0a',
+                                 out_dl_vlan_enable=True,
+                                 in_dl_vlan_enable=True,
+                                 out_vlan_vid=100,
+                                 out_vlan_pcp=0,
+                                 out_vlan_tpid=0x8100,
+                                 out_dl_vlan_cfi=0,
+                                 in_vlan_vid=100,
+                                 in_vlan_pcp=0,
+                                 in_vlan_tpid=0x0800,
+                                 in_dl_vlan_cfi=0):
+    """
+    Return a simple dataplane ether packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destinatino MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    if (out_dl_vlan_enable and in_dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src, type=out_vlan_tpid) / \
+              scapy.Dot1Q(prio=out_vlan_pcp, id=out_dl_vlan_cfi, vlan=out_vlan_vid)
+        pkt = pkt / scapy.Dot1Q(prio=in_vlan_pcp, id=in_dl_vlan_cfi, vlan=in_vlan_vid, type=in_vlan_tpid)
+
+    elif (out_dl_vlan_enable and (not in_dl_vlan_enable)):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src) / \
+              scapy.Dot1Q(prio=out_vlan_pcp, id=out_dl_vlan_cfi, vlan=out_vlan_vid)
+
+    elif ((not out_dl_vlan_enable) and in_dl_vlan_enable):
+        assert (0)  # shall not have this case
+    else:
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+
+    pkt = pkt / ("D" * (pktlen - len(pkt)))
+    return pkt
+
+
+def do_barrier(ctrl, timeout=-1):
+    """
+    Do a barrier command
+    Return 0 on success, -1 on error
+    """
+    b = ofp.message.barrier_request()
+    (resp, pkt) = ctrl.transact(b, timeout=timeout)
+    if resp is None:
+        raise AssertionError("barrier failed")
+    # We'll trust the transaction processing in the controller that xid matched
+    return 0 # for backwards compatibility
+
+def port_config_get(controller, port_no):
+    """
+    Get a port's configuration
+
+    Gets the switch feature configuration and grabs one port's
+    configuration
+
+    @returns (hwaddr, config, advert) The hwaddress, configuration and
+    advertised values
+    """
+
+    if ofp.OFP_VERSION <= 3:
+        request = ofp.message.features_request()
+        reply, _ = controller.transact(request)
+        if reply is None:
+            logging.warn("Get feature request failed")
+            return None, None, None
+        logging.debug(reply.show())
+        ports = reply.ports
+    else:
+        request = ofp.message.port_desc_stats_request()
+        # TODO do multipart correctly
+        reply, _ = controller.transact(request)
+        if reply is None:
+            logging.warn("Port desc stats request failed")
+            return None, None, None
+        logging.debug(reply.show())
+        ports = reply.entries
+
+    for port in ports:
+        if port.port_no == port_no:
+            return (port.hw_addr, port.config, port.advertised)
+
+    logging.warn("Did not find port number for port config")
+    return None, None, None
+
+def port_config_set(controller, port_no, config, mask):
+    """
+    Set the port configuration according the given parameters
+
+    Gets the switch feature configuration and updates one port's
+    configuration value according to config and mask
+    """
+    logging.info("Setting port " + str(port_no) + " to config " + str(config))
+
+    hw_addr, _, _ = port_config_get(controller, port_no)
+
+    mod = ofp.message.port_mod()
+    mod.port_no = port_no
+    if hw_addr != None:
+        mod.hw_addr = hw_addr
+    mod.config = config
+    mod.mask = mask
+    mod.advertise = 0 # No change
+    controller.message_send(mod)
+    return 0
+
+def receive_pkt_check(dp, pkt, yes_ports, no_ports, assert_if):
+    """
+    Check for proper receive packets across all ports
+    @param dp The dataplane object
+    @param pkt Expected packet; may be None if yes_ports is empty
+    @param yes_ports Set or list of ports that should recieve packet
+    @param no_ports Set or list of ports that should not receive packet
+    @param assert_if Object that implements assertXXX
+
+    DEPRECATED in favor in verify_packets
+    """
+
+    exp_pkt_arg = None
+    if oftest.config["relax"]:
+        exp_pkt_arg = pkt
+
+    for ofport in yes_ports:
+        logging.debug("Checking for pkt on port " + str(ofport))
+        (rcv_port, rcv_pkt, pkt_time) = dp.poll(
+            port_number=ofport, exp_pkt=exp_pkt_arg)
+        assert_if.assertTrue(rcv_pkt is not None,
+                             "Did not receive pkt on " + str(ofport))
+        if not oftest.dataplane.match_exp_pkt(pkt, rcv_pkt):
+            logging.debug("Expected %s" % format_packet(pkt))
+            logging.debug("Received %s" % format_packet(rcv_pkt))
+        assert_if.assertTrue(oftest.dataplane.match_exp_pkt(pkt, rcv_pkt),
+                             "Received packet does not match expected packet " +
+                             "on port " + str(ofport))
+    if len(no_ports) > 0:
+        time.sleep(oftest.ofutils.default_negative_timeout)
+    for ofport in no_ports:
+        logging.debug("Negative check for pkt on port " + str(ofport))
+        (rcv_port, rcv_pkt, pkt_time) = dp.poll(
+            port_number=ofport, timeout=0, exp_pkt=exp_pkt_arg)
+        assert_if.assertTrue(rcv_pkt is None,
+                             "Unexpected pkt on port " + str(ofport))
+
+
+def receive_pkt_verify(parent, egr_ports, exp_pkt, ing_port):
+    """
+    Receive a packet and verify it matches an expected value
+    @param egr_port A single port or list of ports
+
+    parent must implement dataplane, assertTrue and assertEqual
+
+    DEPRECATED in favor in verify_packets
+    """
+    exp_pkt_arg = None
+    if oftest.config["relax"]:
+        exp_pkt_arg = exp_pkt
+
+    if type(egr_ports) == type([]):
+        egr_port_list = egr_ports
+    else:
+        egr_port_list = [egr_ports]
+
+    # Expect a packet from each port on egr port list
+    for egr_port in egr_port_list:
+        check_port = egr_port
+        if egr_port == ofp.OFPP_IN_PORT:
+            check_port = ing_port
+        (rcv_port, rcv_pkt, pkt_time) = parent.dataplane.poll(
+            port_number=check_port, exp_pkt=exp_pkt_arg)
+
+        if rcv_pkt is None:
+            logging.error("ERROR: No packet received from " +
+                                str(check_port))
+
+        parent.assertTrue(rcv_pkt is not None,
+                          "Did not receive packet port " + str(check_port))
+        logging.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
+                            str(rcv_port))
+
+        if str(exp_pkt) != str(rcv_pkt):
+            logging.error("ERROR: Packet match failed.")
+            logging.debug("Expected len " + str(len(exp_pkt)) + ": "
+                                + str(exp_pkt).encode('hex'))
+            logging.debug("Received len " + str(len(rcv_pkt)) + ": "
+                                + str(rcv_pkt).encode('hex'))
+            logging.debug("Expected packet: " + inspect_packet(scapy.Ether(str(exp_pkt))))
+            logging.debug("Received packet: " + inspect_packet(scapy.Ether(str(rcv_pkt))))
+        parent.assertEqual(str(exp_pkt), str(rcv_pkt),
+                           "Packet match error on port " + str(check_port))
+
+def match_verify(parent, req_match, res_match):
+    """
+    Verify flow matches agree; if they disagree, report where
+
+    parent must implement assertEqual
+    Use str() to ensure content is compared and not pointers
+    """
+
+    parent.assertEqual(req_match.wildcards, res_match.wildcards,
+                       'Match failed: wildcards: ' + hex(req_match.wildcards) +
+                       " != " + hex(res_match.wildcards))
+    parent.assertEqual(req_match.in_port, res_match.in_port,
+                       'Match failed: in_port: ' + str(req_match.in_port) +
+                       " != " + str(res_match.in_port))
+    parent.assertEqual(str(req_match.eth_src), str(res_match.eth_src),
+                       'Match failed: eth_src: ' + str(req_match.eth_src) +
+                       " != " + str(res_match.eth_src))
+    parent.assertEqual(str(req_match.eth_dst), str(res_match.eth_dst),
+                       'Match failed: eth_dst: ' + str(req_match.eth_dst) +
+                       " != " + str(res_match.eth_dst))
+    parent.assertEqual(req_match.vlan_vid, res_match.vlan_vid,
+                       'Match failed: vlan_vid: ' + str(req_match.vlan_vid) +
+                       " != " + str(res_match.vlan_vid))
+    parent.assertEqual(req_match.vlan_pcp, res_match.vlan_pcp,
+                       'Match failed: vlan_pcp: ' +
+                       str(req_match.vlan_pcp) + " != " +
+                       str(res_match.vlan_pcp))
+    parent.assertEqual(req_match.eth_type, res_match.eth_type,
+                       'Match failed: eth_type: ' + str(req_match.eth_type) +
+                       " != " + str(res_match.eth_type))
+
+    if (not(req_match.wildcards & ofp.OFPFW_DL_TYPE)
+        and (req_match.eth_type == IP_ETHERTYPE)):
+        parent.assertEqual(req_match.ip_dscp, res_match.ip_dscp,
+                           'Match failed: ip_dscp: ' + str(req_match.ip_dscp) +
+                           " != " + str(res_match.ip_dscp))
+        parent.assertEqual(req_match.ip_proto, res_match.ip_proto,
+                           'Match failed: ip_proto: ' + str(req_match.ip_proto) +
+                           " != " + str(res_match.ip_proto))
+        parent.assertEqual(req_match.ipv4_src, res_match.ipv4_src,
+                           'Match failed: ipv4_src: ' + str(req_match.ipv4_src) +
+                           " != " + str(res_match.ipv4_src))
+        parent.assertEqual(req_match.ipv4_dst, res_match.ipv4_dst,
+                           'Match failed: ipv4_dst: ' + str(req_match.ipv4_dst) +
+                           " != " + str(res_match.ipv4_dst))
+
+        if (not(req_match.wildcards & ofp.OFPFW_NW_PROTO)
+            and ((req_match.ip_proto == TCP_PROTOCOL)
+                 or (req_match.ip_proto == UDP_PROTOCOL))):
+            parent.assertEqual(req_match.tcp_src, res_match.tcp_src,
+                               'Match failed: tcp_src: ' +
+                               str(req_match.tcp_src) +
+                               " != " + str(res_match.tcp_src))
+            parent.assertEqual(req_match.tcp_dst, res_match.tcp_dst,
+                               'Match failed: tcp_dst: ' +
+                               str(req_match.tcp_dst) +
+                               " != " + str(res_match.tcp_dst))
+
+def packet_to_flow_match(parent, packet):
+    match = oftest.parse.packet_to_flow_match(packet)
+    if ofp.OFP_VERSION in [1, 2]:
+        match.wildcards |= required_wildcards(parent)
+    else:
+        # TODO remove incompatible OXM entries
+        pass
+    return match
+
+def flow_msg_create(parent, pkt, ing_port=None, action_list=None, wildcards=None,
+               egr_ports=None, egr_queue=None, check_expire=False, in_band=False):
+    """
+    Create a flow message
+
+    Match on packet with given wildcards.
+    See flow_match_test for other parameter descriptoins
+    @param egr_queue if not None, make the output an enqueue action
+    @param in_band if True, do not wildcard ingress port
+    @param egr_ports None (drop), single port or list of ports
+    """
+    match = oftest.parse.packet_to_flow_match(pkt)
+    parent.assertTrue(match is not None, "Flow match from pkt failed")
+    if wildcards is None:
+        wildcards = required_wildcards(parent)
+    if in_band:
+        wildcards &= ~ofp.OFPFW_IN_PORT
+    match.wildcards = wildcards
+    match.in_port = ing_port
+
+    if type(egr_ports) == type([]):
+        egr_port_list = egr_ports
+    else:
+        egr_port_list = [egr_ports]
+
+    request = ofp.message.flow_add()
+    request.match = match
+    request.buffer_id = 0xffffffff
+    if check_expire:
+        request.flags |= ofp.OFPFF_SEND_FLOW_REM
+        request.hard_timeout = 1
+
+    if ofp.OFP_VERSION == 1:
+        actions = request.actions
+    else:
+        actions = []
+        request.instructions.append(ofp.instruction.apply_actions(actions))
+
+    if action_list is not None:
+        actions.extend(action_list)
+
+    # Set up output/enqueue action if directed
+    if egr_queue is not None:
+        parent.assertTrue(egr_ports is not None, "Egress port not set")
+        act = ofp.action.enqueue()
+        for egr_port in egr_port_list:
+            act.port = egr_port
+            act.queue_id = egr_queue
+            actions.append(act)
+    elif egr_ports is not None:
+        for egr_port in egr_port_list:
+            act = ofp.action.output()
+            act.port = egr_port
+            actions.append(act)
+
+    logging.debug(request.show())
+
+    return request
+
+def flow_msg_install(parent, request, clear_table_override=None):
+    """
+    Install a flow mod message in the switch
+
+    @param parent Must implement controller, assertEqual, assertTrue
+    @param request The request, all set to go
+    @param clear_table If true, clear the flow table before installing
+    """
+
+    clear_table = test_param_get('clear_table', default=True)
+    if(clear_table_override != None):
+        clear_table = clear_table_override
+
+    if clear_table:
+        logging.debug("Clear flow table")
+        delete_all_flows(parent.controller)
+
+    logging.debug("Insert flow")
+    parent.controller.message_send(request)
+
+    do_barrier(parent.controller)
+
+def flow_match_test_port_pair(parent, ing_port, egr_ports, wildcards=None,
+                              vlan_vid=-1, pkt=None, exp_pkt=None,
+                              action_list=None):
+    """
+    Flow match test on single TCP packet
+    @param egr_ports A single port or list of ports
+
+    Run test with packet through switch from ing_port to egr_port
+    See flow_match_test for parameter descriptions
+    """
+
+    if wildcards is None:
+        wildcards = required_wildcards(parent)
+    logging.info("Pkt match test: " + str(ing_port) + " to " +
+                       str(egr_ports))
+    logging.debug("  WC: " + hex(wildcards) + " vlan: " + str(vlan_vid))
+    if pkt is None:
+        pkt = simple_tcp_packet(dl_vlan_enable=(vlan_vid >= 0), vlan_vid=vlan_vid)
+    if exp_pkt is None:
+        exp_pkt = pkt
+
+    request = flow_msg_create(parent, pkt, ing_port=ing_port,
+                              wildcards=wildcards, egr_ports=egr_ports,
+                              action_list=action_list)
+
+    flow_msg_install(parent, request)
+
+    logging.debug("Send packet: " + str(ing_port) + " to " +
+                        str(egr_ports))
+    parent.dataplane.send(ing_port, str(pkt))
+
+    exp_ports = [ing_port if port == ofp.OFPP_IN_PORT else port for port in egr_ports]
+    verify_packets(parent, exp_pkt, exp_ports)
+
+def flow_match_test_pktout(parent, ing_port, egr_ports,
+                           vlan_vid=-1, pkt=None, exp_pkt=None,
+                           action_list=None):
+    """
+    Packet-out test on single TCP packet
+    @param egr_ports A single port or list of ports
+
+    Run test sending packet-out to egr_ports. The goal is to test the actions
+    taken on the packet, not the matching which is of course irrelevant.
+    See flow_match_test for parameter descriptions
+    """
+
+    if pkt is None:
+        pkt = simple_tcp_packet(dl_vlan_enable=(vlan_vid >= 0), vlan_vid=vlan_vid)
+    if exp_pkt is None:
+        exp_pkt = pkt
+
+    msg = ofp.message.packet_out()
+    msg.in_port = ing_port
+    msg.buffer_id = 0xffffffff
+    msg.data = str(pkt)
+    if action_list is not None:
+        for act in action_list:
+            msg.actions.append(act)
+
+    # Set up output action
+    if egr_ports is not None:
+        for egr_port in egr_ports:
+            act = ofp.action.output()
+            act.port = egr_port
+            msg.actions.append(act)
+
+    logging.debug(msg.show())
+    parent.controller.message_send(msg)
+
+    exp_ports = [ing_port if port == ofp.OFPP_IN_PORT else port for port in egr_ports]
+    verify_packets(parent, exp_pkt, exp_ports)
+
+def get_egr_list(parent, of_ports, how_many, exclude_list=[]):
+    """
+    Generate a list of ports avoiding those in the exclude list
+    @param parent Supplies logging
+    @param of_ports List of OF port numbers
+    @param how_many Number of ports to be added to the list
+    @param exclude_list List of ports not to be used
+    @returns An empty list if unable to find enough ports
+    """
+
+    if how_many == 0:
+        return []
+
+    count = 0
+    egr_ports = []
+    for egr_idx in range(len(of_ports)):
+        if of_ports[egr_idx] not in exclude_list:
+            egr_ports.append(of_ports[egr_idx])
+            count += 1
+            if count >= how_many:
+                return egr_ports
+    logging.debug("Could not generate enough egress ports for test")
+    return []
+
+def flow_match_test(parent, port_map, wildcards=None, vlan_vid=-1, pkt=None,
+                    exp_pkt=None, action_list=None,
+                    max_test=0, egr_count=1, ing_port=False):
+    """
+    Run flow_match_test_port_pair on all port pairs and packet-out
+
+    @param max_test If > 0 no more than this number of tests are executed.
+    @param parent Must implement controller, dataplane, assertTrue, assertEqual
+    and logging
+    @param pkt If not None, use this packet for ingress
+    @param wildcards For flow match entry
+    @param vlan_vid If not -1, and pkt is None, create a pkt w/ VLAN tag
+    @param exp_pkt If not None, use this as the expected output pkt; els use pkt
+    @param action_list Additional actions to add to flow mod
+    @param egr_count Number of egress ports; -1 means get from config w/ dflt 2
+    """
+    if wildcards is None:
+        wildcards = required_wildcards(parent)
+    of_ports = port_map.keys()
+    of_ports.sort()
+    parent.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+    test_count = 0
+
+    if egr_count == -1:
+        egr_count = test_param_get('egr_count', default=2)
+
+    for ing_idx in range(len(of_ports)):
+        ingress_port = of_ports[ing_idx]
+        egr_ports = get_egr_list(parent, of_ports, egr_count,
+                                 exclude_list=[ingress_port])
+        if ing_port:
+            egr_ports.append(ofp.OFPP_IN_PORT)
+        if len(egr_ports) == 0:
+            parent.assertTrue(0, "Failed to generate egress port list")
+
+        flow_match_test_port_pair(parent, ingress_port, egr_ports,
+                                  wildcards=wildcards, vlan_vid=vlan_vid,
+                                  pkt=pkt, exp_pkt=exp_pkt,
+                                  action_list=action_list)
+        test_count += 1
+        if (max_test > 0) and (test_count > max_test):
+            logging.info("Ran " + str(test_count) + " tests; exiting")
+            break
+
+    if not test_param_get('pktout_actions', default=True):
+        return
+
+    ingress_port = of_ports[0]
+    egr_ports = get_egr_list(parent, of_ports, egr_count,
+                             exclude_list=[ingress_port])
+    if ing_port:
+        egr_ports.append(ofp.OFPP_IN_PORT)
+    flow_match_test_pktout(parent, ingress_port, egr_ports,
+                           vlan_vid=vlan_vid,
+                           pkt=pkt, exp_pkt=exp_pkt,
+                           action_list=action_list)
+
+def test_param_get(key, default=None):
+    """
+    Return value passed via test-params if present
+
+    @param key The lookup key
+    @param default Default value to use if not found
+
+    If the pair 'key=val' appeared in the string passed to --test-params
+    on the command line, return val (as interpreted by exec).  Otherwise
+    return default value.
+
+    WARNING: TEST PARAMETERS MUST BE PYTHON IDENTIFIERS;
+    eg egr_count, not egr-count.
+    """
+    try:
+        exec oftest.config["test_params"]
+    except:
+        return default
+
+    try:
+        return eval(str(key))
+    except:
+        return default
+
+def action_generate(parent, field_to_mod, mod_field_vals):
+    """
+    Create an action to modify the field indicated in field_to_mod
+
+    @param parent Must implement, assertTrue
+    @param field_to_mod The field to modify as a string name
+    @param mod_field_vals Hash of values to use for modified values
+    """
+
+    act = None
+
+    if field_to_mod in ['pktlen']:
+        return None
+
+    if field_to_mod == 'eth_dst':
+        act = ofp.action.set_dl_dst()
+        act.dl_addr = oftest.parse.parse_mac(mod_field_vals['eth_dst'])
+    elif field_to_mod == 'eth_src':
+        act = ofp.action.set_dl_src()
+        act.dl_addr = oftest.parse.parse_mac(mod_field_vals['eth_src'])
+    elif field_to_mod == 'dl_vlan_enable':
+        if not mod_field_vals['dl_vlan_enable']: # Strip VLAN tag
+            act = ofp.action.strip_vlan()
+        # Add VLAN tag is handled by vlan_vid field
+        # Will return None in this case
+    elif field_to_mod == 'vlan_vid':
+        act = ofp.action.set_vlan_vid()
+        act.vlan_vid = mod_field_vals['vlan_vid']
+    elif field_to_mod == 'vlan_pcp':
+        act = ofp.action.set_vlan_pcp()
+        act.vlan_pcp = mod_field_vals['vlan_pcp']
+    elif field_to_mod == 'ip_src':
+        act = ofp.action.set_nw_src()
+        act.nw_addr = oftest.parse.parse_ip(mod_field_vals['ip_src'])
+    elif field_to_mod == 'ip_dst':
+        act = ofp.action.set_nw_dst()
+        act.nw_addr = oftest.parse.parse_ip(mod_field_vals['ip_dst'])
+    elif field_to_mod == 'ip_tos':
+        act = ofp.action.set_nw_tos()
+        act.nw_tos = mod_field_vals['ip_tos']
+    elif field_to_mod == 'tcp_sport':
+        act = ofp.action.set_tp_src()
+        act.tp_port = mod_field_vals['tcp_sport']
+    elif field_to_mod == 'tcp_dport':
+        act = ofp.action.set_tp_dst()
+        act.tp_port = mod_field_vals['tcp_dport']
+    elif field_to_mod == 'udp_sport':
+        act = ofp.action.set_tp_src()
+        act.tp_port = mod_field_vals['udp_sport']
+    elif field_to_mod == 'udp_dport':
+        act = ofp.action.set_tp_dst()
+        act.tp_port = mod_field_vals['udp_dport']
+    else:
+        parent.assertTrue(0, "Unknown field to modify: " + str(field_to_mod))
+
+    return act
+
+def pkt_action_setup(parent, start_field_vals={}, mod_field_vals={},
+                     mod_fields=[], tp="tcp", check_test_params=False):
+    """
+    Set up the ingress and expected packet and action list for a test
+
+    @param parent Must implement assertTrue
+    @param start_field_values Field values to use for ingress packet (optional)
+    @param mod_field_values Field values to use for modified packet (optional)
+    @param mod_fields The list of fields to be modified by the switch in the test.
+    @params check_test_params If True, will check the parameters vid, add_vlan
+    and strip_vlan from the command line.
+
+    Returns a triple:  pkt-to-send, expected-pkt, action-list
+    """
+
+    new_actions = []
+
+    base_pkt_params = {}
+    base_pkt_params['pktlen'] = 100
+    base_pkt_params['eth_dst'] = '00:DE:F0:12:34:56'
+    base_pkt_params['eth_src'] = '00:23:45:67:89:AB'
+    base_pkt_params['dl_vlan_enable'] = False
+    base_pkt_params['vlan_vid'] = 2
+    base_pkt_params['vlan_pcp'] = 0
+    base_pkt_params['ip_src'] = '192.168.0.1'
+    base_pkt_params['ip_dst'] = '192.168.0.2'
+    base_pkt_params['ip_tos'] = 0
+    if tp == "tcp":
+        base_pkt_params['tcp_sport'] = 1234
+        base_pkt_params['tcp_dport'] = 80
+    elif tp == "udp":
+        base_pkt_params['udp_sport'] = 1234
+        base_pkt_params['udp_dport'] = 80
+    for keyname in start_field_vals.keys():
+        base_pkt_params[keyname] = start_field_vals[keyname]
+
+    mod_pkt_params = {}
+    mod_pkt_params['pktlen'] = 100
+    mod_pkt_params['eth_dst'] = '00:21:0F:ED:CB:A9'
+    mod_pkt_params['eth_src'] = '00:ED:CB:A9:87:65'
+    mod_pkt_params['dl_vlan_enable'] = False
+    mod_pkt_params['vlan_vid'] = 3
+    mod_pkt_params['vlan_pcp'] = 7
+    mod_pkt_params['ip_src'] = '10.20.30.40'
+    mod_pkt_params['ip_dst'] = '50.60.70.80'
+    mod_pkt_params['ip_tos'] = 0xf0
+    if tp == "tcp":
+        mod_pkt_params['tcp_sport'] = 4321
+        mod_pkt_params['tcp_dport'] = 8765
+    elif tp == "udp":
+        mod_pkt_params['udp_sport'] = 4321
+        mod_pkt_params['udp_dport'] = 8765
+    for keyname in mod_field_vals.keys():
+        mod_pkt_params[keyname] = mod_field_vals[keyname]
+
+    # Check for test param modifications
+    strip = False
+    if check_test_params:
+        add_vlan = test_param_get('add_vlan')
+        strip_vlan = test_param_get('strip_vlan')
+        vid = test_param_get('vid')
+
+        if add_vlan and strip_vlan:
+            parent.assertTrue(0, "Add and strip VLAN both specified")
+
+        if vid:
+            base_pkt_params['dl_vlan_enable'] = True
+            base_pkt_params['vlan_vid'] = vid
+            if 'vlan_vid' in mod_fields:
+                mod_pkt_params['vlan_vid'] = vid + 1
+
+        if add_vlan:
+            base_pkt_params['dl_vlan_enable'] = False
+            mod_pkt_params['dl_vlan_enable'] = True
+            mod_pkt_params['pktlen'] = base_pkt_params['pktlen'] + 4
+            mod_fields.append('pktlen')
+            mod_fields.append('dl_vlan_enable')
+            if 'vlan_vid' not in mod_fields:
+                mod_fields.append('vlan_vid')
+        elif strip_vlan:
+            base_pkt_params['dl_vlan_enable'] = True
+            mod_pkt_params['dl_vlan_enable'] = False
+            mod_pkt_params['pktlen'] = base_pkt_params['pktlen'] - 4
+            mod_fields.append('dl_vlan_enable')
+            mod_fields.append('pktlen')
+
+    if tp == "tcp":
+        packet_builder = simple_tcp_packet
+    elif tp == "udp":
+        packet_builder = simple_udp_packet
+    else:
+        raise NotImplementedError("unknown transport protocol %s" % tp)
+
+    # Build the ingress packet
+    ingress_pkt = packet_builder(**base_pkt_params)
+
+    # Build the expected packet, modifying the indicated fields
+    for item in mod_fields:
+        base_pkt_params[item] = mod_pkt_params[item]
+        act = action_generate(parent, item, mod_pkt_params)
+        if act:
+            new_actions.append(act)
+
+    expected_pkt = packet_builder(**base_pkt_params)
+
+    return (ingress_pkt, expected_pkt, new_actions)
+
+# Generate a simple "drop" flow mod
+# If in_band is true, then only drop from first test port
+def flow_mod_gen(port_map, in_band):
+    request = ofp.message.flow_add()
+    request.match.wildcards = ofp.OFPFW_ALL
+    if in_band:
+        request.match.wildcards = ofp.OFPFW_ALL - ofp.OFPFW_IN_PORT
+        for of_port, ifname in port_map.items(): # Grab first port
+            break
+        request.match.in_port = of_port
+    request.buffer_id = 0xffffffff
+    return request
+
+def skip_message_emit(parent, s):
+    """
+    Print out a 'skipped' message to stderr
+
+    @param s The string to print out to the log file
+    """
+    global skipped_test_count
+
+    skipped_test_count += 1
+    logging.info("Skipping: " + s)
+    if oftest.config["debug"] < logging.WARNING:
+        sys.stderr.write("(skipped) ")
+    else:
+        sys.stderr.write("(S)")
+
+
+def all_stats_get(parent):
+    """
+    Get the aggregate stats for all flows in the table
+    @param parent Test instance with controller connection and assert
+    @returns dict with keys flows, packets, bytes, active (flows),
+    lookups, matched
+    """
+    stat_req = ofp.message.aggregate_stats_request()
+    stat_req.match = ofp.match()
+    stat_req.match.wildcards = ofp.OFPFW_ALL
+    stat_req.table_id = 0xff
+    stat_req.out_port = ofp.OFPP_NONE
+
+    rv = {}
+
+    (reply, pkt) = parent.controller.transact(stat_req)
+    parent.assertTrue(len(reply.entries) == 1, "Did not receive flow stats reply")
+
+    for obj in reply.entries:
+        (rv["flows"], rv["packets"], rv["bytes"]) = (obj.flow_count,
+                                                  obj.packet_count, obj.byte_count)
+        break
+
+    request = ofp.message.table_stats_request()
+    (reply , pkt) = parent.controller.transact(request)
+
+
+    (rv["active"], rv["lookups"], rv["matched"]) = (0,0,0)
+    for obj in reply.entries:
+        rv["active"] += obj.active_count
+        rv["lookups"] += obj.lookup_count
+        rv["matched"] += obj.matched_count
+
+    return rv
+
+_import_blacklist.add('FILTER')
+FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.'
+                for x in range(256)])
+
+def hex_dump_buffer(src, length=16):
+    """
+    Convert src to a hex dump string and return the string
+    @param src The source buffer
+    @param length The number of bytes shown in each line
+    @returns A string showing the hex dump
+    """
+    result = ["\n"]
+    for i in xrange(0, len(src), length):
+       chars = src[i:i+length]
+       hex = ' '.join(["%02x" % ord(x) for x in chars])
+       printable = ''.join(["%s" % ((ord(x) <= 127 and
+                                     FILTER[ord(x)]) or '.') for x in chars])
+       result.append("%04x  %-*s  %s\n" % (i, length*3, hex, printable))
+    return ''.join(result)
+
+def format_packet(pkt):
+    return "Packet length %d \n%s" % (len(str(pkt)),
+                                      hex_dump_buffer(str(pkt)))
+
+def inspect_packet(pkt):
+    """
+    Wrapper around scapy's show() method.
+    @returns A string showing the dissected packet.
+    """
+    from cStringIO import StringIO
+    out = None
+    backup = sys.stdout
+    try:
+        tmp = StringIO()
+        sys.stdout = tmp
+        pkt.show2()
+        out = tmp.getvalue()
+        tmp.close()
+    finally:
+        sys.stdout = backup
+    return out
+
+def nonstandard(cls):
+    """
+    Testcase decorator that marks the test as being non-standard.
+    These tests are not automatically added to the "standard" group.
+    """
+    cls._nonstandard = True
+    return cls
+
+def disabled(cls):
+    """
+    Testcase decorator that marks the test as being disabled.
+    These tests are not automatically added to the "standard" group or
+    their module's group.
+    """
+    cls._disabled = True
+    return cls
+
+def group(name):
+    """
+    Testcase decorator that adds the test to a group.
+    """
+    def fn(cls):
+        if not hasattr(cls, "_groups"):
+            cls._groups = []
+        cls._groups.append(name)
+        return cls
+    return fn
+
+def version(ver):
+    """
+    Testcase decorator that specifies which versions of OpenFlow the test
+    supports. The default is 1.0+. This decorator may only be used once.
+
+    Supported syntax:
+    1.0 -> 1.0
+    1.0,1.2,1.3 -> 1.0, 1.2, 1.3
+    1.0+ -> 1.0, 1.1, 1.2, 1.3
+    """
+    versions = parse_version(ver)
+    def fn(cls):
+        cls._versions = versions
+        return cls
+    return fn
+
+def parse_version(ver):
+    allowed_versions = ["1.0", "1.1", "1.2", "1.3"]
+    if re.match("^1\.\d+$", ver):
+        versions = set([ver])
+    elif re.match("^(1\.\d+)\+$", ver):
+        if not ver[:-1] in allowed_versions:
+            raise ValueError("invalid OpenFlow version %s" % ver[:-1])
+        versions = set()
+        if ver != "1.1+": versions.add("1.0")
+        if ver != "1.2+": versions.add("1.1")
+        if ver != "1.3+": versions.add("1.2")
+        versions.add("1.3")
+    else:
+        versions = set(ver.split(','))
+
+    for version in versions:
+        if not version in allowed_versions:
+            raise ValueError("invalid OpenFlow version %s" % version)
+
+    return versions
+
+assert(parse_version("1.0") == set(["1.0"]))
+assert(parse_version("1.0,1.2,1.3") == set(["1.0", "1.2", "1.3"]))
+assert(parse_version("1.0+") == set(["1.0", "1.1", "1.2", "1.3"]))
+
+def get_stats(test, req):
+    """
+    Retrieve a list of stats entries. Handles OFPSF_REPLY_MORE.
+    """
+    msgtype = ofp.OFPT_STATS_REPLY
+    more_flag = ofp.OFPSF_REPLY_MORE
+    stats = []
+    reply, _ = test.controller.transact(req)
+    test.assertTrue(reply is not None, "No response to stats request")
+    test.assertEquals(reply.type, msgtype, "Response had unexpected message type")
+    stats.extend(reply.entries)
+    while reply.flags & more_flag != 0:
+        reply, pkt = test.controller.poll(exp_msg=msgtype)
+        test.assertTrue(reply is not None, "No response to stats request")
+        stats.extend(reply.entries)
+    return stats
+
+def get_flow_stats(test, match, table_id=None,
+                   out_port=None, out_group=None,
+                   cookie=0, cookie_mask=0):
+    """
+    Retrieve a list of flow stats entries.
+    """
+
+    if table_id == None:
+        if ofp.OFP_VERSION <= 2:
+            table_id = 0xff
+        else:
+            table_id = ofp.OFPTT_ALL
+
+    if out_port == None:
+        if ofp.OFP_VERSION == 1:
+            out_port = ofp.OFPP_NONE
+        else:
+            out_port = ofp.OFPP_ANY
+
+    if out_group == None:
+        if ofp.OFP_VERSION > 1:
+            out_group = ofp.OFPP_ANY
+
+    req = ofp.message.flow_stats_request(match=match,
+                                         table_id=table_id,
+                                         out_port=out_port)
+    if ofp.OFP_VERSION > 1:
+        req.out_group = out_group
+        req.cookie = cookie
+        req.cookie_mask = cookie_mask
+
+    return get_stats(test, req)
+
+def get_port_stats(test, port_no):
+    """
+    Retrieve a list of port stats entries.
+    """
+    req = ofp.message.port_stats_request(port_no=port_no)
+    return get_stats(test, req)
+
+def get_queue_stats(test, port_no, queue_id):
+    """
+    Retrieve a list of queue stats entries.
+    """
+    req = ofp.message.queue_stats_request(port_no=port_no, queue_id=queue_id)
+    return get_stats(test, req)
+
+def verify_flow_stats(test, match, table_id=0xff,
+                      initial=[],
+                      pkts=None, bytes=None):
+    """
+    Verify that flow stats changed as expected.
+
+    Optionally takes an 'initial' list of stats entries, as returned by
+    get_flow_stats(). If 'initial' is not given the counters are assumed to
+    begin at 0.
+    """
+
+    def accumulate(stats):
+        pkts_acc = bytes_acc = 0
+        for stat in stats:
+            pkts_acc += stat.packet_count
+            bytes_acc += stat.byte_count
+        return (pkts_acc, bytes_acc)
+
+    pkts_before, bytes_before = accumulate(initial)
+
+    # Wait 10s for counters to update
+    pkt_diff = byte_diff = None
+    for i in range(0, 100):
+        stats = get_flow_stats(test, match, table_id=table_id)
+        pkts_after, bytes_after = accumulate(stats)
+        pkt_diff = pkts_after - pkts_before
+        byte_diff = bytes_after - bytes_before
+        if (pkts == None or pkt_diff >= pkts) and \
+           (bytes == None or byte_diff >= bytes):
+            break
+        time.sleep(0.1)
+
+    if pkts != None:
+        test.assertEquals(pkt_diff, pkts, "Flow packet counter not updated properly (expected increase of %d, got increase of %d)" % (pkts, pkt_diff))
+
+    if bytes != None:
+        test.assertTrue(byte_diff >= bytes and byte_diff <= bytes*1.1,
+                        "Flow byte counter not updated properly (expected increase of %d, got increase of %d)" % (bytes, byte_diff))
+
+def verify_port_stats(test, port,
+                      initial=[],
+                      tx_pkts=None, rx_pkts=None,
+                      tx_bytes=None, rx_bytes=None):
+    """
+    Verify that port stats changed as expected.
+
+    Optionally takes an 'initial' list of stats entries, as returned by
+    get_port_stats(). If 'initial' is not given the counters are assumed to
+    begin at 0.
+    """
+    def accumulate(stats):
+        tx_pkts_acc = rx_pkts_acc = tx_bytes_acc = rx_bytes_acc = 0
+        for stat in stats:
+            tx_pkts_acc += stat.tx_packets
+            rx_pkts_acc += stat.rx_packets
+            tx_bytes_acc += stat.tx_bytes
+            rx_bytes_acc += stat.rx_bytes
+        return (tx_pkts_acc, rx_pkts_acc, tx_bytes_acc, rx_bytes_acc)
+
+    tx_pkts_before, rx_pkts_before, \
+        tx_bytes_before, rx_bytes_before = accumulate(initial)
+
+    # Wait 10s for counters to update
+    for i in range(0, 100):
+        stats = get_port_stats(test, port)
+        tx_pkts_after, rx_pkts_after, \
+            tx_bytes_after, rx_bytes_after = accumulate(stats)
+        tx_pkts_diff = tx_pkts_after - tx_pkts_before
+        rx_pkts_diff = rx_pkts_after - rx_pkts_before
+        tx_bytes_diff = tx_bytes_after - tx_bytes_before
+        rx_bytes_diff = rx_bytes_after - rx_bytes_before
+        if (tx_pkts == None or tx_pkts <= tx_pkts_diff) and \
+           (rx_pkts == None or rx_pkts <= rx_pkts_diff) and \
+           (tx_bytes == None or tx_bytes <= tx_bytes_diff) and \
+           (rx_bytes == None or rx_bytes <= rx_bytes_diff):
+            break
+        time.sleep(0.1)
+
+    if (tx_pkts != None):
+        test.assertGreaterEqual(tx_pkts_diff, tx_pkts,
+            "Port TX packet counter is not updated correctly (expected increase of %d, got increase of %d)" % (tx_pkts, tx_pkts_diff))
+    if (rx_pkts != None):
+        test.assertGreaterEqual(rx_pkts_diff, rx_pkts,
+            "Port RX packet counter is not updated correctly (expected increase of %d, got increase of %d)" % (rx_pkts, rx_pkts_diff))
+    if (tx_bytes != None):
+        test.assertGreaterEqual(tx_bytes_diff, tx_bytes,
+            "Port TX byte counter is not updated correctly (expected increase of %d, got increase of %d)" % (tx_bytes, tx_bytes_diff))
+    if (rx_bytes != None):
+        test.assertGreaterEqual(rx_bytes_diff, rx_bytes,
+            "Port RX byte counter is not updated correctly (expected increase of %d, got increase of %d)" % (rx_bytes, rx_bytes_diff))
+
+def verify_queue_stats(test, port_no, queue_id,
+                       initial=[],
+                       pkts=None, bytes=None):
+    """
+    Verify that queue stats changed as expected.
+
+    Optionally takes an 'initial' list of stats entries, as returned by
+    get_queue_stats(). If 'initial' is not given the counters are assumed to
+    begin at 0.
+    """
+    def accumulate(stats):
+        pkts_acc = bytes_acc = 0
+        for stat in stats:
+            pkts_acc += stat.tx_packets
+            bytes_acc += stat.tx_bytes
+        return (pkts_acc, bytes_acc)
+
+    pkts_before, bytes_before = accumulate(initial)
+
+    # Wait 10s for counters to update
+    pkt_diff = byte_diff = None
+    for i in range(0, 100):
+        stats = get_queue_stats(test, port_no, queue_id)
+        pkts_after, bytes_after = accumulate(stats)
+        pkt_diff = pkts_after - pkts_before
+        byte_diff = bytes_after - bytes_before
+        if (pkts == None or pkt_diff >= pkts) and \
+           (bytes == None or byte_diff >= bytes):
+            break
+        time.sleep(0.1)
+
+    if pkts != None:
+        test.assertEquals(pkt_diff, pkts, "Queue packet counter not updated properly (expected increase of %d, got increase of %d)" % (pkts, pkt_diff))
+
+    if bytes != None:
+        test.assertTrue(byte_diff >= bytes and byte_diff <= bytes*1.1,
+                        "Queue byte counter not updated properly (expected increase of %d, got increase of %d)" % (bytes, byte_diff))
+
+def packet_in_match(msg, data, in_port=None, reason=None):
+    """
+    Check whether the packet_in message 'msg' has fields matching 'data',
+    'in_port', and 'reason'.
+
+    This function handles truncated packet_in data. The 'in_port' and 'reason'
+    parameters are optional.
+
+    @param msg packet_in message
+    @param data Expected packet_in data
+    @param in_port Expected packet_in in_port, or None
+    @param reason Expected packet_in reason, or None
+    """
+
+    if ofp.OFP_VERSION <= 2:
+        pkt_in_port = msg.in_port
+    else:
+        oxms = { type(oxm): oxm for oxm in msg.match.oxm_list }
+        if ofp.oxm.in_port in oxms:
+            pkt_in_port = oxms[ofp.oxm.in_port].value
+        else:
+            logging.warn("Missing in_port in packet-in message")
+            pkt_in_port = None
+
+    if in_port != None and in_port != pkt_in_port:
+        logging.debug("Incorrect packet_in in_port (expected %d, received %d)", in_port, pkt_in_port)
+        return False
+
+    if reason != None and reason != msg.reason:
+        logging.debug("Incorrect packet_in reason (expected %d, received %d)", reason, msg.reason)
+        return False
+
+    # Check that one of the packets is a prefix of the other.
+    # The received packet may be either truncated or padded, but not both.
+    # (Some of the padding may be truncated but that's irrelevant). We
+    # need to check that the smaller packet is a prefix of the larger one.
+    # Note that this check succeeds if the switch sends a zero-length
+    # packet-in.
+    compare_len = min(len(msg.data), len(data))
+    if data[:compare_len] != msg.data[:compare_len]:
+        logging.debug("Incorrect packet_in data")
+        logging.debug("Expected %s" % format_packet(data[:compare_len]))
+        logging.debug("Received %s" % format_packet(msg.data[:compare_len]))
+        return False
+
+    return True
+
+def verify_packet_in(test, data, in_port, reason, controller=None):
+    """
+    Assert that the controller receives a packet_in message matching data 'data'
+    from port 'in_port' with reason 'reason'. Does not trigger the packet_in
+    itself, that's up to the test case.
+
+    @param test Instance of base_tests.SimpleProtocol
+    @param pkt String to expect as the packet_in data
+    @param in_port OpenFlow port number to expect as the packet_in in_port
+    @param reason One of OFPR_* to expect as the packet_in reason
+    @param controller Controller instance, defaults to test.controller
+    @returns The received packet-in message
+    """
+
+    if controller == None:
+        controller = test.controller
+
+    end_time = time.time() + oftest.ofutils.default_timeout
+
+    while True:
+        msg, _ = controller.poll(ofp.OFPT_PACKET_IN, end_time - time.time())
+        if not msg:
+            # Timeout
+            break
+        elif packet_in_match(msg, data, in_port, reason):
+            # Found a matching message
+            break
+
+    test.assertTrue(msg is not None, 'Packet in message not received on port %r' % in_port)
+    return msg
+
+def verify_no_packet_in(test, data, in_port, controller=None):
+    """
+    Assert that the controller does not receive a packet_in message matching
+    data 'data' from port 'in_port'.
+
+    @param test Instance of base_tests.SimpleProtocol
+    @param pkt String to expect as the packet_in data
+    @param in_port OpenFlow port number to expect as the packet_in in_port
+    @param controller Controller instance, defaults to test.controller
+    """
+
+    if controller == None:
+        controller = test.controller
+
+    # Negative test, need to wait a short amount of time before checking we
+    # didn't receive the message.
+    time.sleep(oftest.ofutils.default_negative_timeout)
+
+    # Check every packet_in queued in the controller
+    while True:
+        msg, _ = controller.poll(ofp.OFPT_PACKET_IN, timeout=0)
+        if msg == None:
+            # No more queued packet_in messages
+            break
+        elif packet_in_match(msg, data, in_port, None):
+            # Found a matching message
+            break
+
+    if in_port == None:
+        test.assertTrue(msg == None, "Did not expect a packet-in message on any port")
+    else:
+        test.assertTrue(msg == None, "Did not expect a packet-in message on port %d" % in_port)
+
+def openflow_ports(num=None):
+    """
+    Return a list of 'num' OpenFlow port numbers
+
+    If 'num' is None, return all available ports. Otherwise, limit the length
+    of the result to 'num' and raise an exception if not enough ports are
+    available.
+    """
+    ports = sorted(oftest.config["port_map"].keys())
+    if num != None and len(ports) < num:
+        raise Exception("test requires %d ports but only %d are available" % (num, len(ports)))
+    return ports[:num]
+
+def verify_packet(test, pkt, ofport):
+    """
+    Check that an expected packet is received
+    """
+    logging.debug("Checking for pkt on port %r", ofport)
+    (rcv_port, rcv_pkt, pkt_time) = test.dataplane.poll(port_number=ofport, exp_pkt=str(pkt))
+    test.assertTrue(rcv_pkt != None, "Did not receive pkt on %r" % ofport)
+    return (rcv_port, rcv_pkt, pkt_time)
+
+def verify_no_packet(test, pkt, ofport):
+    """
+    Check that a particular packet is not received
+    """
+    logging.debug("Negative check for pkt on port %r", ofport)
+    (rcv_port, rcv_pkt, pkt_time) = \
+        test.dataplane.poll(
+            port_number=ofport, exp_pkt=str(pkt),
+            timeout=oftest.ofutils.default_negative_timeout)
+    test.assertTrue(rcv_pkt == None, "Received packet on %r" % ofport)
+
+def verify_no_other_packets(test):
+    """
+    Check that no unexpected packets are received
+
+    This is a no-op if the --relax option is in effect.
+    """
+    if oftest.config["relax"]:
+        return
+    logging.debug("Checking for unexpected packets on all ports")
+    (rcv_port, rcv_pkt, pkt_time) = test.dataplane.poll(timeout=oftest.ofutils.default_negative_timeout)
+    if rcv_pkt != None:
+        logging.debug("Received unexpected packet on port %r: %s", rcv_port, format_packet(rcv_pkt))
+    test.assertTrue(rcv_pkt == None, "Unexpected packet on port %r" % rcv_port)
+
+def verify_packets(test, pkt, ofports):
+    """
+    Check that a packet is received on certain ports
+
+    Also verifies that the packet is not received on any other ports, and that no
+    other packets are received (unless --relax is in effect).
+
+    This covers the common and simplest cases for checking dataplane outputs.
+    For more complex usage, like multiple different packets being output, or
+    multiple packets on the same port, use the primitive verify_packet,
+    verify_no_packet, and verify_no_other_packets functions directly.
+    """
+    pkt = str(pkt)
+    for ofport in openflow_ports():
+        if ofport in ofports:
+            verify_packet(test, pkt, ofport)
+        else:
+            verify_no_packet(test, pkt, ofport)
+    verify_no_other_packets(test)
+
+def verify_no_errors(ctrl):
+    error, _ = ctrl.poll(ofp.OFPT_ERROR, 0)
+    if error:
+        raise AssertionError("unexpected error type=%d code=%d" % (error.err_type, error.code))
+
+def verify_capability(test, capability):
+    """
+    Return True if DUT supports the specified capability.
+
+    @param test Instance of base_tests.SimpleProtocol
+    @param capability One of ofp_capabilities.
+    """
+    logging.info("Verifing that capability code is valid.")
+    test.assertIn(capability, ofp.const.ofp_capabilities_map,
+                  "Capability code %d does not exist." % capability)
+    capability_str = ofp.const.ofp_capabilities_map[capability]
+
+    logging.info(("Sending features_request to test if capability "
+                  "%s is supported."), capability_str)
+    req = ofp.message.features_request()
+    res, raw = test.controller.transact(req)
+    test.assertIsNotNone(res, "Did not receive a response from the DUT.")
+    test.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
+                     ("Unexpected packet type %d received in response to "
+                      "OFPT_FEATURES_REQUEST") % res.type)
+    logging.info("Received features_reply.")
+
+    if (res.capabilities & capability) > 0:
+        logging.info("Switch capabilities bitmask claims to support %s",
+                     capability_str)
+        return True, res.capabilities
+    else:
+        logging.info("Capabilities bitmask does not support %s.",
+                     capability_str)
+        return False, res.capabilities
+
+def verify_configuration_flag(test, flag):
+    """
+    Return True if DUT supports specified configuration flag.
+
+    @param test Instance of base_tests.SimpleProtocol
+    @param flag One of ofp_config_flags.
+    @returns (supported, flags) Bool if flag is set and flag values.
+    """
+    logging.info("Verifing that flag is valid.")
+    test.assertIn(flag, ofp.const.ofp_config_flags_map,
+                  "flag  %s does not exist." % flag)
+    flag_str = ofp.const.ofp_config_flags_map[flag]
+
+    logging.info("Sending OFPT_GET_CONFIG_REQUEST.")
+    req = ofp.message.get_config_request()
+    rv = test.controller.message_send(req)
+    test.assertNotEqual(rv, -1, "Not able to send get_config_request.")
+
+    logging.info("Expecting OFPT_GET_CONFIG_REPLY ")
+    (res, pkt) = test.controller.poll(exp_msg=ofp.OFPT_GET_CONFIG_REPLY,
+                                      timeout=2)
+    test.assertIsNotNone(res, "Did not receive OFPT_GET_CONFIG_REPLY")
+    logging.info("Received OFPT_GET_CONFIG_REPLY ")
+
+    if res.flags == flag:
+        logging.info("%s flag is set.", flag_str)
+        return True, res.flags
+    else:
+        logging.info("%s flag is not set.", flag_str)
+        return False, res.flags
+
+__all__ = list(set(locals()) - _import_blacklist)
diff --git a/Fabric/Utilities/src/python/oftest/utils.py b/Fabric/Utilities/src/python/oftest/utils.py
new file mode 100644
index 0000000..ebc168d
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/utils.py
@@ -0,0 +1,779 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import Queue
+import itertools
+
+from oftest.testutils import *
+from accton_util import *
+
+"""
+MISC
+"""
+
+def print_port_stats(test, port):
+    entries = get_port_stats(test, port)
+    for item in entries:
+        packet_rcv          = item.rx_packets
+        packet_rcv_dropped  = item.rx_dropped
+        packet_rcv_errors   = item.rx_errors
+
+        packet_sent         = item.tx_packets
+        packet_sent_dropped = item.tx_dropped
+        packet_sent_errors  = item.tx_errors
+
+    print "\nPort %d stats count: tx %d rx %d - tx_dropped %d rx_dropped %d - tx_errors %d rx_errors %d" % (
+        port, packet_sent, packet_rcv, packet_sent_dropped, packet_rcv_dropped, packet_sent_errors, packet_rcv_errors
+        )
+
+def filter_dhcp(controller):
+    match = ofp.match( )
+    match.oxm_list.append( ofp.oxm.eth_type( 0x0800 ) )
+    match.oxm_list.append( ofp.oxm.ip_proto( 17 ) )
+    match.oxm_list.append( ofp.oxm.udp_src( 68 ) )
+    match.oxm_list.append( ofp.oxm.udp_dst( 67 ))
+    request = ofp.message.flow_add(
+        table_id=60,
+        cookie=42,
+        match=match,
+        instructions=[ofp.instruction.clear_actions( )],
+        buffer_id=ofp.OFP_NO_BUFFER,
+        priority=1
+        )
+    controller.message_send( request )
+    do_barrier( controller )
+
+def filter_ipv6(controller):
+    match = ofp.match( )
+    match.oxm_list.append( ofp.oxm.eth_type( 0x86dd ) )
+    request = ofp.message.flow_add(
+        table_id=60,
+        cookie=42,
+        match=match,
+        instructions=[ofp.instruction.clear_actions( )],
+        buffer_id=ofp.OFP_NO_BUFFER,
+        priority=1
+        )
+    controller.message_send( request )
+    do_barrier( controller )
+
+def filter_igmp(controller):
+    match = ofp.match( )
+    match.oxm_list.append( ofp.oxm.eth_type( 0x0800 ) )
+    match.oxm_list.append( ofp.oxm.ip_proto( 2 ) )
+    request = ofp.message.flow_add(
+        table_id=60,
+        cookie=42,
+        match=match,
+        instructions=[ofp.instruction.clear_actions( )],
+        buffer_id=ofp.OFP_NO_BUFFER,
+        priority=1
+        )
+    controller.message_send( request )
+    do_barrier( controller )
+
+"""
+MULTICAST Pipelines
+"""
+
+def fill_mcast_pipeline_L3toL2(
+    controller,
+    logging,
+    ports,
+    is_ingress_tagged,
+    is_egress_tagged,
+    is_vlan_translated,
+    is_max_vlan
+    ):
+    """
+    This method, according to the scenario, fills properly
+    the pipeline. The method generates using ports data the
+    necessary information to fill the multicast pipeline and
+    fills properly the pipeline which consists in this scenario:
+
+    i) to create l2 interface groups;
+    ii) to create l3 multicast groups;
+    iii) to add multicast flows;
+    iv) to add termination; flows;
+    v) to add vlan flows
+
+    Scenarios:
+    1) ingress untagged, egress untagged
+    2) ingress untagged, egress tagged
+    3) ingress tagged, egress untagged
+    4) ingress tagged, egress tagged, no translation
+    5) ingress tagged, egress tagged, translation
+    """
+
+    MAX_INTERNAL_VLAN           = 4094
+    # Used for no translation
+    FIXED_VLAN                  = 300
+    Groups                      = Queue.LifoQueue( )
+    L2_Groups                   = []
+    port_to_in_vlan             = {}
+    port_to_out_vlan            = {}
+    port_to_src_mac             = {}
+    port_to_src_mac_str         = {}
+    port_to_dst_mac             = {}
+    port_to_dst_mac_str         = {}
+    port_to_src_ip              = {}
+    port_to_src_ip_str          = {}
+    src_ip_0                    = 0xc0a80100
+    src_ip_0_str                = "192.168.1.%s"
+    dst_ip                      = 0xe0000001
+    switch_mac                  = [ 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 ]
+
+    for port in ports:
+        in_vlan_id  = port + 1
+        out_vlan_id = MAX_INTERNAL_VLAN - port
+        if is_max_vlan and not is_vlan_translated:
+            in_vlan_id  = MAX_INTERNAL_VLAN
+            out_vlan_id = MAX_INTERNAL_VLAN
+        elif not is_max_vlan and not is_vlan_translated:
+            in_vlan_id  = FIXED_VLAN
+            out_vlan_id = FIXED_VLAN
+        src_mac                     = [ 0x00, 0x11, 0x11, 0x11, 0x11, port ]
+        src_mac_str                 = ':'.join( [ '%02X' % x for x in src_mac ] )
+        dst_mac                     = [ 0x01, 0x00, 0x5e, 0x01, 0x01, port ]
+        dst_mac_str                 = ':'.join( [ '%02X' % x for x in dst_mac ] )
+        src_ip                      = src_ip_0 + port
+        src_ip_str                  = src_ip_0_str % port
+        port_to_in_vlan[port]       = in_vlan_id
+        port_to_out_vlan[port]      = out_vlan_id
+        port_to_src_mac[port]       = src_mac
+        port_to_src_mac_str[port]   = src_mac_str
+        port_to_dst_mac[port]       = dst_mac
+        port_to_dst_mac_str[port]   = dst_mac_str
+        port_to_src_ip[port]        = src_ip
+        port_to_src_ip_str[port]    = src_ip_str
+
+    for in_port in ports:
+
+        L2_Groups = []
+        # add vlan flows table
+        add_one_vlan_table_flow( controller, in_port, 1, port_to_in_vlan[in_port], flag=VLAN_TABLE_FLAG_ONLY_TAG )
+        if not is_ingress_tagged:
+            add_one_vlan_table_flow( controller, in_port, 1, port_to_in_vlan[in_port], flag=VLAN_TABLE_FLAG_ONLY_UNTAG )
+        elif is_vlan_translated:
+            add_one_vlan_table_flow_translation( controller, in_port, port_to_in_vlan[in_port], port_to_out_vlan[in_port], flag=VLAN_TABLE_FLAG_ONLY_TAG)
+        # add termination flow
+        if not is_vlan_translated:
+            add_termination_flow( controller, in_port, 0x0800, switch_mac, port_to_in_vlan[in_port] )
+        else:
+            add_termination_flow( controller, in_port, 0x0800, switch_mac, port_to_out_vlan[in_port] )
+
+        for out_port in ports:
+            if out_port == in_port:
+                continue
+            # add l2 interface group, vlan_id equals for each port and must coincide with mcast_group vlan_id
+            if not is_vlan_translated:
+                l2gid, msg = add_one_l2_interface_group( controller, out_port, vlan_id=port_to_in_vlan[in_port],
+                is_tagged=is_egress_tagged, send_barrier=True )
+            else:
+                l2gid, msg = add_one_l2_interface_group( controller, out_port, vlan_id=port_to_out_vlan[in_port],
+                is_tagged=is_egress_tagged, send_barrier=True )
+            Groups._put( l2gid )
+            L2_Groups.append( l2gid )
+
+        # add l3 mcast group
+        if not is_vlan_translated:
+            mcat_group_msg = add_l3_mcast_group( controller, port_to_in_vlan[in_port], in_port, L2_Groups )
+        else:
+            mcat_group_msg = add_l3_mcast_group( controller, port_to_out_vlan[in_port], in_port, L2_Groups )
+        Groups._put( mcat_group_msg.group_id )
+        # add mcast routing flow
+        if not is_vlan_translated:
+            add_mcast4_routing_flow( controller, port_to_in_vlan[in_port], port_to_src_ip[in_port], 0, dst_ip, mcat_group_msg.group_id )
+        else:
+            add_mcast4_routing_flow( controller, port_to_out_vlan[in_port], port_to_src_ip[in_port], 0, dst_ip, mcat_group_msg.group_id )
+
+    return (
+        port_to_in_vlan,
+        port_to_out_vlan,
+        port_to_src_mac_str,
+        port_to_dst_mac_str,
+        port_to_src_ip,
+        port_to_src_ip_str,
+        Groups
+        )
+
+def fill_mcast_pipeline_L3toL3(
+    controller,
+    logging,
+    ports,
+    is_ingress_tagged,
+    is_egress_tagged,
+    is_vlan_translated,
+    is_max_vlan
+    ):
+    """
+    This method, according to the scenario, fills properly
+    the pipeline. The method generates using ports data the
+    necessary information to fill the multicast pipeline and
+    fills properly the pipeline which consists in this scenario:
+
+    i) to create l2 interface groups;
+    ii)to create l3 interface groups;
+    iii) to create l3 multicast groups;
+    iv) to add multicast flows;
+    v) to add termination; flows;
+    vi) to add vlan flows
+
+    Scenarios:
+    1) ingress tagged, egress tagged, translation
+    """
+
+    Groups                      = Queue.LifoQueue( )
+    MAX_INTERNAL_VLAN           = 4094
+    port_to_in_vlan             = {}
+    port_to_out_vlan            = {}
+    port_to_src_mac             = {}
+    port_to_src_mac_str         = {}
+    port_to_dst_mac             = {}
+    port_to_dst_mac_str         = {}
+    port_to_src_ip              = {}
+    port_to_src_ip_str          = {}
+    port_to_intf_src_mac        = {}
+    port_to_intf_src_mac_str    = {}
+    src_ip_0                    = 0xc0a80100
+    src_ip_0_str                = "192.168.1.%s"
+    dst_ip                      = 0xe0000001
+    switch_mac                  = [ 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 ]
+
+    for port in ports:
+        in_vlan_id                     = port + 1
+        out_vlan_id                    = MAX_INTERNAL_VLAN - port
+        src_mac                        = [ 0x00, 0x11, 0x11, 0x11, 0x11, port ]
+        src_mac_str                    = ':'.join( [ '%02X' % x for x in src_mac ] )
+        dst_mac                        = [ 0x01, 0x00, 0x5e, 0x01, 0x01, port ]
+        dst_mac_str                    = ':'.join( [ '%02X' % x for x in dst_mac ] )
+        src_ip                         = src_ip_0 + port
+        src_ip_str                     = src_ip_0_str % port
+        intf_src_mac                   = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, port ]
+        intf_src_mac_str               = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+        port_to_in_vlan[port]          = in_vlan_id
+        port_to_out_vlan[port]         = out_vlan_id
+        port_to_src_mac[port]          = src_mac
+        port_to_src_mac_str[port]      = src_mac_str
+        port_to_dst_mac[port]          = dst_mac
+        port_to_dst_mac_str[port]      = dst_mac_str
+        port_to_src_ip[port]           = src_ip
+        port_to_src_ip_str[port]       = src_ip_str
+        port_to_intf_src_mac[port]     = intf_src_mac
+        port_to_intf_src_mac_str[port] = intf_src_mac_str
+
+    for port in ports:
+        L3_Groups = []
+        for other_port in ports:
+            # add l2 interface group
+            l2gid, msg = add_one_l2_interface_group( controller, other_port, vlan_id=port_to_out_vlan[other_port],
+            is_tagged=True, send_barrier=True )
+            Groups._put( l2gid )
+            # add l3 interface group
+            l3group_ucast_msg = add_l3_interface_group( controller, other_port, port_to_out_vlan[other_port], port_to_in_vlan[other_port],
+            port_to_intf_src_mac[other_port] )
+            L3_Groups.append(l3group_ucast_msg.group_id)
+            Groups._put( l3group_ucast_msg.group_id )
+
+        # add mcast group
+        mcat_group_msg = add_l3_mcast_group( controller, port_to_in_vlan[port], port_to_in_vlan[port], L3_Groups )
+        do_barrier(controller)
+        Groups._put( mcat_group_msg.group_id )
+        # add mcast flow
+        add_mcast4_routing_flow( controller, port_to_in_vlan[port], port_to_src_ip[port], 0, dst_ip, mcat_group_msg.group_id, True )
+        # add termination flow
+        add_termination_flow( controller, port, 0x0800, switch_mac, port_to_in_vlan[port] )
+        # add vlan flow table
+        add_one_vlan_table_flow( controller, port, 1, port_to_in_vlan[port], flag=VLAN_TABLE_FLAG_ONLY_TAG )
+
+    return (
+        port_to_in_vlan,
+        port_to_out_vlan,
+        port_to_src_mac_str,
+        port_to_dst_mac_str,
+        port_to_src_ip,
+        port_to_src_ip_str,
+        port_to_intf_src_mac_str,
+        Groups
+        )
+
+"""
+VPWS Pipeline
+"""
+
+OF_DPA_MPLS_L2_VPN_Label     = 1
+OF_DPA_MPLS_Tunnel_Label_1   = 3
+OF_DPA_MPLS_Tunnel_Label_2   = 4
+
+EGRESS_UNTAGGED     = 1
+EGRESS_TAGGED       = 2
+EGRESS_TAGGED_TRANS = 3
+
+
+def fill_pw_initiation_pipeline(
+    controller,
+    logging,
+    in_port,
+    out_port,
+    ingress_tags,
+    egress_tag,
+    mpls_labels
+    ):
+    """
+    This method, according to the scenario, fills properly
+    the pw pipeline. The method generates using ports data the
+    necessary information to fill the pw pipeline and
+    fills properly the pipeline which consists into:
+
+    """
+
+    Groups                  = Queue.LifoQueue( )
+    out_vlan                = 4094
+    port_to_in_vlan_1       = {}
+    port_to_in_vlan_2       = {}
+    port_to_in_vlan_3       = {}
+    port_to_src_mac         = {}
+    port_to_src_mac_str     = {}
+    port_to_dst_mac         = {}
+    port_to_dst_mac_str     = {}
+    port_to_mpls_label_1    = {}
+    port_to_mpls_label_2    = {}
+    port_to_mpls_label_pw   = {}
+    ports                   = [in_port, out_port]
+
+    for port in ports:
+        in_vlan_id_1                = port + 1
+        in_vlan_id_2                = port + 100
+        in_vlan_id_3                = port + 300
+        mpls_label_1                = port + 100
+        mpls_label_2                = port + 200
+        mpls_label_pw               = port + 300
+        port_to_in_vlan_1[port]     = in_vlan_id_1
+        port_to_in_vlan_2[port]     = in_vlan_id_2
+        port_to_in_vlan_3[port]     = in_vlan_id_3
+        src_mac                     = [ 0x00, 0x00, 0x00, 0x00, 0x11, port ]
+        src_mac_str                 = ':'.join( [ '%02X' % x for x in src_mac ] )
+        dst_mac                     = [ 0x00, 0x00, 0x00, 0x11, 0x11, port ]
+        dst_mac_str                 = ':'.join( [ '%02X' % x for x in dst_mac ] )
+        port_to_src_mac[port]       = src_mac
+        port_to_src_mac_str[port]   = src_mac_str
+        port_to_dst_mac[port]       = dst_mac
+        port_to_dst_mac_str[port]   = dst_mac_str
+        port_to_mpls_label_1[port]  = mpls_label_1
+        port_to_mpls_label_2[port]  = mpls_label_2
+        port_to_mpls_label_pw[port] = mpls_label_pw
+
+    # add l2 interface group, we have to pop the VLAN;
+    l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+        ctrl=controller,
+        port=out_port,
+        vlan_id=out_vlan,
+        is_tagged=False,
+        send_barrier=False
+        )
+    Groups._put( l2_intf_gid )
+    # add MPLS interface group
+    mpls_intf_gid, mpls_intf_msg = add_mpls_intf_group(
+        ctrl=controller,
+        ref_gid=l2_intf_gid,
+        dst_mac=port_to_dst_mac[in_port],
+        src_mac=port_to_src_mac[out_port],
+        vid=out_vlan,
+        index=in_port
+        )
+    Groups._put( mpls_intf_gid )
+    mpls_gid = mpls_intf_gid
+    # add MPLS tunnel label groups, the number depends on the labels
+    if mpls_labels == 2:
+        mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
+        ctrl=controller,
+        ref_gid=mpls_intf_gid,
+        subtype=OF_DPA_MPLS_Tunnel_Label_2,
+        index=in_port,
+        label=port_to_mpls_label_2[in_port]
+        )
+        Groups._put( mpls_tunnel_gid )
+        mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
+            ctrl=controller,
+            ref_gid=mpls_tunnel_gid,
+            subtype=OF_DPA_MPLS_Tunnel_Label_1,
+            index=in_port,
+            label=port_to_mpls_label_1[in_port]
+            )
+        Groups._put( mpls_tunnel_gid )
+        mpls_gid = mpls_tunnel_gid
+    elif mpls_labels == 1:
+        mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
+            ctrl=controller,
+            ref_gid=mpls_intf_gid,
+            subtype=OF_DPA_MPLS_Tunnel_Label_1,
+            index=in_port,
+            label=port_to_mpls_label_1[in_port]
+            )
+        Groups._put( mpls_tunnel_gid )
+        mpls_gid = mpls_tunnel_gid
+    # add MPLS L2 VPN group
+    mpls_l2_vpn_gid, mpls_l2_vpn_msg = add_mpls_label_group(
+        ctrl=controller,
+        subtype=OF_DPA_MPLS_L2_VPN_Label,
+        index=in_port,
+        ref_gid=mpls_gid,
+        push_l2_header=True,
+        push_vlan=True,
+        push_mpls_header=True,
+        push_cw=True,
+        set_mpls_label=port_to_mpls_label_pw[in_port],
+        set_bos=1,
+        cpy_ttl_outward=True
+    )
+    Groups._put( mpls_l2_vpn_gid )
+    # add MPLS L2 port flow
+    add_mpls_l2_port_flow(
+        ctrl=controller,
+        of_port=in_port,
+        mpls_l2_port=in_port,
+        tunnel_index=1,
+        ref_gid=mpls_l2_vpn_gid
+        )
+    # add VLAN flows table
+    if ingress_tags == 2:
+        if egress_tag == EGRESS_TAGGED:
+            add_one_vlan_1_table_flow_pw(
+                ctrl=controller,
+                of_port=in_port,
+                tunnel_index=1,
+                new_outer_vlan_id=-1,
+                outer_vlan_id=port_to_in_vlan_2[in_port],
+                inner_vlan_id=port_to_in_vlan_1[in_port],
+                )
+        elif egress_tag == EGRESS_TAGGED_TRANS:
+            add_one_vlan_1_table_flow_pw(
+                ctrl=controller,
+                of_port=in_port,
+                tunnel_index=1,
+                new_outer_vlan_id=port_to_in_vlan_3[in_port],
+                outer_vlan_id=port_to_in_vlan_2[in_port],
+                inner_vlan_id=port_to_in_vlan_1[in_port],
+                )
+        add_one_vlan_table_flow(
+            ctrl=controller,
+            of_port=in_port,
+            vlan_id=port_to_in_vlan_2[in_port],
+            flag=VLAN_TABLE_FLAG_ONLY_STACKED,
+            )
+    elif ingress_tags == 1:
+        if egress_tag == EGRESS_TAGGED:
+            add_one_vlan_table_flow_pw(
+                ctrl=controller,
+                of_port=in_port,
+                tunnel_index=1,
+                vlan_id=port_to_in_vlan_1[in_port],
+                flag=VLAN_TABLE_FLAG_ONLY_TAG,
+                )
+        elif egress_tag == EGRESS_TAGGED_TRANS:
+            add_one_vlan_table_flow_pw(
+                ctrl=controller,
+                of_port=in_port,
+                tunnel_index=1,
+                vlan_id=port_to_in_vlan_1[in_port],
+                new_vlan_id=port_to_in_vlan_3[in_port],
+                flag=VLAN_TABLE_FLAG_ONLY_TAG,
+                )
+    elif ingress_tags == 0:
+        filter_dhcp(controller)
+        filter_ipv6(controller)
+        filter_igmp(controller)
+        if egress_tag == EGRESS_UNTAGGED:
+            add_one_vlan_table_flow_pw(
+                ctrl=controller,
+                of_port=in_port,
+                tunnel_index=1,
+                flag=VLAN_TABLE_FLAG_ONLY_UNTAG,
+                )
+        elif egress_tag == EGRESS_TAGGED:
+            add_one_vlan_table_flow_pw(
+                ctrl=controller,
+                of_port=in_port,
+                tunnel_index=1,
+                vlan_id=port_to_in_vlan_1[in_port],
+                flag=VLAN_TABLE_FLAG_ONLY_UNTAG,
+                )
+
+    return (
+        port_to_mpls_label_2,
+        port_to_mpls_label_1,
+        port_to_mpls_label_pw,
+        port_to_in_vlan_3,
+        port_to_in_vlan_2,
+        port_to_in_vlan_1,
+        port_to_src_mac_str,
+        port_to_dst_mac_str,
+        Groups
+        )
+
+MPLS_FLOW_TABLE_0           = 23
+OF_DPA_MPLS_SWAP_Label      = 5
+
+def fill_pw_intermediate_transport_pipeline(
+    controller,
+    logging,
+    ports,
+    mpls_labels
+    ):
+    """
+    This method, according to the scenario, fills properly
+    the pw pipeline. The method generates using ports data the
+    necessary information to fill the pw pipeline and
+    fills properly the pipeline which consists into:
+
+    """
+
+    Groups                  = Queue.LifoQueue( )
+    out_vlan                = 4094
+    port_to_src_mac         = {}
+    port_to_src_mac_str     = {}
+    port_to_dst_mac         = {}
+    port_to_dst_mac_str     = {}
+    port_to_mpls_label_2    = {}
+    port_to_mpls_label_1    = {}
+    port_to_mpls_label_pw   = {}
+    port_to_switch_mac      = {}
+    port_to_switch_mac_str  = {}
+
+    for port in ports:
+        mpls_label_1                    = port + 10
+        mpls_label_2                    = port + 100
+        mpls_label_pw                   = port + 300
+        src_mac                         = [ 0x00, 0x00, 0x00, 0x00, 0x11, port ]
+        src_mac_str                     = ':'.join( [ '%02X' % x for x in src_mac ] )
+        dst_mac                         = [ 0x00, 0x00, 0x00, 0x11, 0x11, port ]
+        dst_mac_str                     = ':'.join( [ '%02X' % x for x in dst_mac ] )
+        switch_mac                      = [ 0x00, 0x00, 0x00, 0x00, 0x00, port ]
+        switch_mac_str                  = ':'.join( [ '%02X' % x for x in switch_mac ] )
+        port_to_src_mac[port]           = src_mac
+        port_to_src_mac_str[port]       = src_mac_str
+        port_to_dst_mac[port]           = dst_mac
+        port_to_dst_mac_str[port]       = dst_mac_str
+        port_to_mpls_label_1[port]      = mpls_label_1
+        port_to_mpls_label_2[port]      = mpls_label_2
+        port_to_mpls_label_pw[port]     = mpls_label_pw
+        port_to_switch_mac[port]        = switch_mac
+        port_to_switch_mac_str[port]    = switch_mac_str
+
+    for pair in itertools.product(ports, ports):
+        in_port     = pair[0]
+        out_port    = pair[1]
+        if out_port == in_port:
+            continue
+        # add l2 interface group, we have to pop the VLAN;
+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+            ctrl=controller,
+            port=out_port,
+            vlan_id=out_vlan,
+            is_tagged=False,
+            send_barrier=False
+            )
+        Groups._put( l2_intf_gid )
+        # add MPLS interface group
+        mpls_intf_gid, mpls_intf_msg = add_mpls_intf_group(
+            ctrl=controller,
+            ref_gid=l2_intf_gid,
+            dst_mac=port_to_dst_mac[in_port],
+            src_mac=port_to_src_mac[out_port],
+            vid=out_vlan,
+            index=in_port
+            )
+        Groups._put( mpls_intf_gid )
+        # add MPLS flows
+        if mpls_labels >=2:
+            add_mpls_flow_pw(
+                ctrl=controller,
+                action_group_id=mpls_intf_gid,
+                label=port_to_mpls_label_2[in_port],
+                ethertype=0x8847,
+                tunnel_index=1,
+                bos=0
+                )
+        else:
+            mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
+                ctrl=controller,
+                ref_gid=mpls_intf_gid,
+                subtype=OF_DPA_MPLS_Tunnel_Label_2,
+                index=in_port,
+                label=port_to_mpls_label_2[in_port]
+                )
+            Groups._put( mpls_tunnel_gid )
+            mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
+                ctrl=controller,
+                ref_gid=mpls_tunnel_gid,
+                subtype=OF_DPA_MPLS_Tunnel_Label_1,
+                index=in_port,
+                label=port_to_mpls_label_1[in_port]
+                )
+            Groups._put( mpls_tunnel_gid )
+            mpls_swap_gid, mpls_tunnel_msg = add_mpls_swap_label_group(
+                ctrl=controller,
+                ref_gid=mpls_tunnel_gid,
+                subtype=OF_DPA_MPLS_SWAP_Label,
+                index=in_port,
+                label=port_to_mpls_label_pw[in_port]
+                )
+            Groups._put( mpls_swap_gid )
+            add_mpls_flow_pw(
+                ctrl=controller,
+                action_group_id=mpls_swap_gid,
+                label=port_to_mpls_label_pw[in_port],
+                ethertype=0x8847,
+                tunnel_index=1,
+                bos=1,
+                popMPLS=False,
+                popL2=False
+                )
+        # add Termination flow
+        add_termination_flow(
+            ctrl=controller,
+            in_port=in_port,
+            eth_type=0x8847,
+            dst_mac=port_to_switch_mac[in_port],
+            vlanid=out_vlan,
+            goto_table=MPLS_FLOW_TABLE_0)
+        # add VLAN flows
+        add_one_vlan_table_flow(
+            ctrl=controller,
+            of_port=in_port,
+            vlan_id=out_vlan,
+            flag=VLAN_TABLE_FLAG_ONLY_TAG,
+            )
+        add_one_vlan_table_flow(
+            ctrl=controller,
+            of_port=in_port,
+            vlan_id=out_vlan,
+            flag=VLAN_TABLE_FLAG_ONLY_UNTAG
+            )
+
+    return (
+        port_to_mpls_label_2,
+        port_to_mpls_label_1,
+        port_to_mpls_label_pw,
+        port_to_switch_mac_str,
+        port_to_src_mac_str,
+        port_to_dst_mac_str,
+        Groups
+        )
+
+def fill_pw_termination_pipeline(
+    controller,
+    logging,
+    in_port,
+    out_port,
+    egress_tags
+    ):
+    """
+    This method, according to the scenario, fills properly
+    the pw pipeline. The method generates using ports data the
+    necessary information to fill the pw pipeline and
+    fills properly the pipeline which consists into:
+
+    """
+
+    Groups                  = Queue.LifoQueue( )
+    out_vlan                = 4094
+    port_to_mpls_label_pw   = {}
+    port_to_vlan_2          = {}
+    port_to_vlan_1          = {}
+    port_to_switch_mac      = {}
+    port_to_switch_mac_str  = {}
+    ports                   = [in_port, out_port]
+
+    for port in ports:
+        mpls_label_pw                   = port + 300
+        in_vlan_id_1                    = port + 1
+        in_vlan_id_2                    = port + 100
+        switch_mac                      = [ 0x00, 0x00, 0x00, 0x00, 0x11, port ]
+        switch_mac_str                  = ':'.join( [ '%02X' % x for x in switch_mac ] )
+        port_to_mpls_label_pw[port]     = mpls_label_pw
+        port_to_vlan_2[port]            = in_vlan_id_2
+        port_to_vlan_1[port]            = in_vlan_id_1
+        port_to_switch_mac[port]        = switch_mac
+        port_to_switch_mac_str[port]    = switch_mac_str
+
+    # add l2 interface group;
+    if egress_tags == 2:
+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+            ctrl=controller,
+            port=out_port,
+            vlan_id=port_to_vlan_2[out_port],
+            is_tagged=True,
+            send_barrier=False
+            )
+    elif egress_tags == 1:
+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+            ctrl=controller,
+            port=out_port,
+            vlan_id=port_to_vlan_1[out_port],
+            is_tagged=True,
+            send_barrier=False
+            )
+    elif egress_tags == 0:
+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+            ctrl=controller,
+            port=out_port,
+            vlan_id=port_to_vlan_1[out_port],
+            is_tagged=False,
+            send_barrier=False
+            )
+
+    Groups._put( l2_intf_gid )
+    add_mpls_flow_pw(
+        ctrl=controller,
+        action_group_id=l2_intf_gid,
+        label=port_to_mpls_label_pw[out_port],
+        ethertype=0x6558,
+        bos=1,
+        tunnel_index=1,
+        popMPLS=True,
+        popL2=True,
+        of_port=in_port
+        )
+    # add Termination flow
+    add_termination_flow(
+        ctrl=controller,
+        in_port=in_port,
+        eth_type=0x8847,
+        dst_mac=port_to_switch_mac[in_port],
+        vlanid=out_vlan,
+        goto_table=MPLS_FLOW_TABLE_0)
+    # add VLAN flows
+    add_one_vlan_table_flow(
+        ctrl=controller,
+        of_port=in_port,
+        vlan_id=out_vlan,
+        flag=VLAN_TABLE_FLAG_ONLY_TAG,
+        )
+    add_one_vlan_table_flow(
+        ctrl=controller,
+        of_port=in_port,
+        vlan_id=out_vlan,
+        flag=VLAN_TABLE_FLAG_ONLY_UNTAG
+        )
+
+    return (
+        port_to_mpls_label_pw,
+        port_to_vlan_2,
+        port_to_vlan_1,
+        port_to_switch_mac_str,
+        Groups
+        )
diff --git a/Fabric/Utilities/tools/ovs-ctl/README b/Fabric/Utilities/tools/ovs-ctl/README
new file mode 100644
index 0000000..b2378f7
--- /dev/null
+++ b/Fabric/Utilities/tools/ovs-ctl/README
@@ -0,0 +1,212 @@
+###############################################################################
+#
+# ovs-ctl.py
+#
+###############################################################################
+
+ovs-ctl manages the initialization and execution of OVS instances as targets
+for OFTest execution. 
+
+
+-------------------------------------------------------------------------------
+INSTALLATION
+-------------------------------------------------------------------------------
+
+ovs-ctl requires OVS be built and installed on your local machine. 
+If you are new to OVS, the preferred method is:
+
+1. Download openvswitch-X.Y.Z from http://openvswitch.org/releases
+2. Untar, configure, build, and install openvswitch into a useful location:
+
+   # All OVS installations will go in to /opt/ovs:
+   > mkdir -p /opt/ovs
+   
+   # All OVS Source distributions will live in /opt/ovs/src:
+   > mkdir -p /opt/ovs/src
+
+   # Download and untar source for openvswitch 1.4.0:
+   > curl http://openvswitch.org/releases/openvswitch-1.4.0.tar.gz | tar -xzC /opt/ovs/src
+
+   # build and install:
+   > cd /opt/ovs/openvswitch-1.4.0
+   > ./configure --prefix=/opt/ovs/1.4.0 --with-linux=/lib/modules/`uname -r`/build
+   > make
+   > sudo make install
+
+   # Copy the OVS kernel module out of the build tree into the install tree:
+   > sudo cp /opt/ovs/src/openvswitch-1.4.0/datapath/linux/openvswitch_mod.ko /opt/ovs/1.4.0/sbin
+
+
+3. READ the comments and instructions in ovs-ctl-default.example.conf
+
+4. Copy ovs-ctl-default.example.conf from the local directory to /opt/ovs:
+   
+   > sudo cp ovs-ctl-default.example.conf /opt/ovs/ovs-ctl-default.conf
+
+5. Modify /opt/ovs/ovs-ctl-default.conf to match your existing installation(s). 
+   If you followed the directions and used the paths suggested in Step 2, then the default 
+   configuration file should work without modification. 
+   Otherwise, edit to point to your installation directorie(s). 
+
+
+
+-------------------------------------------------------------------------------
+EXAMPLE USAGE
+-------------------------------------------------------------------------------
+
+You can initialize and run your default configuration (as specified in the config files) as follows:
+
+> ./ovs-ctl
+
+You can stop a running configuration as follows:
+
+> ./ovs-ctl --kill
+
+You can initialize and run any configuration (as specified in the config files) as follows:
+
+> ./ovs-ctl --config 1.3.0
+> ./ovs-ctl --config 1.4.0
+> ./ovs-ctl --config MySomeOtherConfiguration
+
+You can output logging and verbose information with the --log and --verbose options. 
+
+By default, OVS is initialized with 4 veth ports. You can change this with the --port-count option. 
+
+
+
+CONFIG FILES
+------------
+
+The configuration file options are just convenient methods of storing values for the command line
+arguments. Every command line argument can be specified as a key in your configuration file. 
+
+You do not need a configuration file at all -- you can specify all required paths and values
+from the command line -- but this is not recommended for regular usage. 
+
+The precedence for these settings is in the following order:
+
+1. Command Line option, if specified, THEN
+2. The [ConfigName] section of all config files, both default, user, or command-line specified, THEN
+3. The [Defaults] section of all config files
+
+
+Note that you may have a section defined in the ovs-ctl-default.conf file, AND in your ~/.ovs-ctl file. 
+The settings will be merged together, with the values in ~/.ovs-ctl taking precedence:
+
+So, for example, you can have the local installation information for 1.4.0 specified in /opt/ovs/ovs-ctl-default.conf as follows:
+
+    [1.4.0]
+    # ovs-1.4.0, configured and built into /opt/ovs/1.4.0
+    # Can be selected with 'ovs-ctl.py --config 1.4.0'
+    ovs_src_dir:/opt/ovs/src/openvswitch-1.4.0
+    ovs_base_dir:/opt/ovs/1.4.0
+    ovs_runtime_dir:/var/run/ovs/1.4.0
+
+This can be used by everyone. 
+
+You can also have user-specific settings in ~/.ovs-ctl for your own execution:
+
+    [1.4.0]
+    # Put logfiles for my personal runs in my ~/ovs-logfiles directory:
+    ovs_vswitchd_log=~/.ovs-logfiles/vswitchd.log
+
+
+
+-------------------------------------------------------------------------------
+OPTIONS AND HELP
+-------------------------------------------------------------------------------
+
+This documentation is minimal.
+
+Please see ./ovs-ctl --help for a full list of options:
+
+usage: ovs-ctl.py [-h] [-cf FILE [FILE ...]] [-c CONFIG] [-d FILE] [-nd]
+                  [--dump-config] [--ovs-vswitchd-schema OVS_VSWITCHD_SCHEMA]
+                  [--ovs-vswitchd-log OVS_VSWITCHD_LOG]
+                  [--ovs-vswitchd OVS_VSWITCHD] [--ovs-vsctl OVS_VSCTL]
+                  [--ovs-ofctl OVS_OFCTL] [--ovsdb-tool OVSDB_TOOL]
+                  [--ovsdb-server OVSDB_SERVER] [--ovs-kmod OVS_KMOD]
+                  [--ovs-src-dir OVS_SRC_DIR] [--ovs-log-dir OVS_LOG_DIR]
+                  [--ovs-version OVS_VERSION] [--ovs-base-dir OVS_BASE_DIR]
+                  [--ovs-runtime-dir OVS_RUNTIME_DIR]
+                  [--ovs-db-sock OVS_DB_SOCK] [--ovs-db-file OVS_DB_FILE]
+                  [--dry] [--log] [--verbose] [--kill] [--keep-veths]
+                  [--no-kmod] [--vlog] [-p PORT_COUNT] [--bridge BRIDGE]
+                  [--cip CIP] [--cport CPORT] [--max_backoff MAX_BACKOFF]
+                  [--keep-db]
+
+optional arguments:
+  -h, --help            show this help message and exit
+  -cf FILE [FILE ...], --config-file FILE [FILE ...]
+                        Load settings from the given config file
+  -c CONFIG, --config CONFIG
+                        Use the specified configuration section
+  -d FILE, --default-config-file FILE
+                        Location of the local default config file
+  -nd, --no-default     Do not load the default config file
+  --dump-config         Dump the loaded configuration settings
+  --ovs-vswitchd-schema OVS_VSWITCHD_SCHEMA
+                        Path to the vswitchd.ovsschema file
+  --ovs-vswitchd-log OVS_VSWITCHD_LOG
+                        Path to the vswitchd log file
+  --ovs-vswitchd OVS_VSWITCHD
+                        Path to the target ovs-vswitchd binary
+  --ovs-vsctl OVS_VSCTL
+                        Path to the target ovs-vsctl binary
+  --ovs-ofctl OVS_OFCTL
+                        Path to the target ovs-ofctl binary
+  --ovsdb-tool OVSDB_TOOL
+                        Path to the target ovsdb-tool binary
+  --ovsdb-server OVSDB_SERVER
+                        Path to the target ovsdb-server binary
+  --ovs-kmod OVS_KMOD   Path to the OVS kernel module
+  --ovs-src-dir OVS_SRC_DIR
+                        Directory for the OVS Source Files
+  --ovs-log-dir OVS_LOG_DIR
+                        Directory for the OVS Runtime Log Files
+  --ovs-version OVS_VERSION
+  --ovs-base-dir OVS_BASE_DIR
+                        OVS Base Installation Directory
+  --ovs-runtime-dir OVS_RUNTIME_DIR
+                        OVS Runtime Directory
+  --ovs-db-sock OVS_DB_SOCK
+                        Domain Socket Location
+  --ovs-db-file OVS_DB_FILE
+                        Location for the OVS database file
+  --dry                 Dry run only. Don't actually do anything
+  --log                 Enable logging
+  --verbose             Enable verbose output information
+  --kill                Kill running OVS
+  --keep-veths          By default, all existing veths will be destroyed and
+                        the veth module removed before initializing. If you
+                        don't want the veth module removed, specify this
+                        argument. Your mileage may vary if you use this.
+  --no-kmod             Do not attempt to insert or remove the OVS kernel
+                        module. Your mileage may vary.
+  --vlog                Tail the running vswitch.log file in a new xterm
+  -p PORT_COUNT, --port-count PORT_COUNT
+                        Number of veth ports to connect.
+  --bridge BRIDGE       Name of OF OVS Bridge
+  --cip CIP             Controller Connection
+  --cport CPORT         Controller Port
+  --max_backoff MAX_BACKOFF
+                        VSwitchD max backoff value
+  --keep-db             By default, a new database is initialized at each
+                        execution. If you want to keep and use the old
+                        database (if it exists), use this option
+
+
+
+
+-------------------------------------------------------------------------------
+TODO
+-------------------------------------------------------------------------------
+
+1. Better documentation. 
+2. Option for automatic downloading, configuration, and installation of OVS. 
+3. Symlinks or alias generation for selecting the correct ovs-* tools for
+   debugging the running configuration. 
+
+
+
+
diff --git a/Fabric/Utilities/tools/ovs-ctl/ovs-ctl-default.example.conf b/Fabric/Utilities/tools/ovs-ctl/ovs-ctl-default.example.conf
new file mode 100644
index 0000000..2996dce
--- /dev/null
+++ b/Fabric/Utilities/tools/ovs-ctl/ovs-ctl-default.example.conf
@@ -0,0 +1,96 @@
+###############################################################################
+#
+# This is the example/default ovs-ctl config file. 
+#
+# ovs-ctl config files will be searched and read, by default, int he following
+# order:
+#
+# /opt/ovs/ovs-ctl-default.conf
+# ~/.ovs-ctl
+#
+# This behavior can be modified and change specifically on the command line:
+#
+# Change the location of the default config file:
+# > ovs-ctl --default-config-file=/path/to/file
+#
+# Disable the default config file:
+# > ovs-ctl --no-default 
+#
+# Read these specific config files:
+# > ovs-ctl --config-file file1 file2 file3
+#
+# Note: The default config file reading behavior is equivalent to:
+#
+# > ovs-ctl --default /opt/ovs/ovs-ctl-default.conf --config-file ~/.ovs-ctl
+# 
+# This is also equivalent to:
+# > ovs-ctl --no-default --config-file /opt/ovs/ovs-ctl-default.conf ~/.ovs-ctl
+#
+#
+###############################################################################
+
+#
+# Default options can be specified here
+#
+[Defaults]
+# Default all configurations to 1.4.0
+config:1.4.0
+
+#
+# Specific OVS configurations go here
+#
+[1.4.0]
+# ovs-1.4.0, configured and built into /opt/ovs/1.4.0
+# Can be selected with 'ovs-ctl.py --config 1.4.0'
+ovs_src_dir:/opt/ovs/src/openvswitch-1.4.0
+ovs_base_dir:/opt/ovs/1.4.0
+ovs_runtime_dir:/var/run/ovs/1.4.0
+
+
+[1.3.0]
+# ovs-1.3.0, configured and built into /opt/ovs/1.3.0
+# Can be selected with 'ovsctl.py --config 1.3.0'
+ovs_src_dir:/opt/ovs/src/openvswitch-1.3.0
+ovs_base_dir:/opt/ovs/1.3.0
+ovs_runtime_dir:/var/run/ovs/1.3.0
+
+[1.2.2]
+# ovs-1.2.2, configured and built into /opt/ovs/1.2.2
+# Can be selected with 'ovsctl.py --config 1.2.2'
+ovs_src_dir:/opt/ovs/src/openvswitch-1.2.2
+ovs_base_dir:/opt/ovs/1.2.2
+ovs_runtime_dir:/var/run/ovs/1.2.2
+
+#
+# In the above configurations, the locations of the tools
+# are derived by ovs-ctl relative to 'ovs_src_dir' and 'ovs_base_dir'
+#
+# Individual tools and locations can be specified directly in 
+# the configuration (as well as the command line):
+#
+# Try:
+# 'ovs-ctl.py --no-default --config-file ovs-ctl-default.example.conf --config MyExample'
+#
+# In general, every command line option can be specified in a config file section. 
+#
+# The precedence of options is:
+#     1. Command Line Options
+#     2. [The Config You Specified]
+#     3. [The Defaults sections]
+#
+
+[MyExampleConfig]
+ovs_vswitchd_schema:/path/to/vswitch/schema/file
+ovs_vswitchdL:/path/to/vswitchd
+ovs_vsctl:/path/to/vsctl
+ovs_ofctl:/path/to/ofctl
+ovsdb_tool:/path/to/ovsdb_tool
+ovsd_db_file:/path/to/ovs_db_file
+ovs_db_sock:/path/to/ovs_db_sock
+ovs_kmod:/path/to/ovs_kmod
+
+
+
+
+
+
diff --git a/Fabric/Utilities/tools/ovs-ctl/ovs-ctl.py b/Fabric/Utilities/tools/ovs-ctl/ovs-ctl.py
new file mode 100755
index 0000000..13e287e
--- /dev/null
+++ b/Fabric/Utilities/tools/ovs-ctl/ovs-ctl.py
@@ -0,0 +1,542 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+#!/usr/bin/python
+
+import os
+import subprocess
+import argparse
+import sys
+import signal
+import time
+import ConfigParser
+import pprint
+
+###############################################################################
+#
+# Arguments
+#
+# Arguments can be specified directly, or via config file. 
+# TODO -- Make this a separate reusable class
+#
+################################################################################
+gBasename = "ovs-ctl"
+
+gConfigParser = argparse.ArgumentParser(description=gBasename, add_help=False)
+
+gConfigParser.add_argument('-cf', '--config-file', 
+                     help="Load settings from the given config file", 
+                     nargs='+', metavar="FILE", 
+                     default=os.path.expanduser("~/."+gBasename))
+
+gConfigParser.add_argument('-c', '--config', 
+                     help="Use the specified configuration section", 
+                     default=None)
+
+gConfigParser.add_argument('-d', '--default-config-file', 
+                     help="Location of the local default config file", 
+                     metavar="FILE", 
+                     default="/opt/ovs/%s-default.conf" % (gBasename))
+
+gConfigParser.add_argument('-nd', '--no-default', 
+                     help="Do not load the default config file", 
+                     action='store_true', default=False)
+gConfigParser.add_argument('--dump-config',
+                     help="Dump the loaded configuration settings", 
+                     action='store_true', default=False)
+
+#
+# Parse the config files first, then parse remaining command line arguments
+#
+gConfig = ConfigParser.SafeConfigParser()
+configArgs, remainingArgs = gConfigParser.parse_known_args()
+
+if not configArgs.no_default:
+    gConfig.read([configArgs.default_config_file])
+
+if isinstance(configArgs.config_file, str):
+    configFiles = [ configArgs.config_file]
+else:
+    configFiles = configArgs.config_file
+
+configFiles = [ os.path.expanduser(x) if x.startswith('~') else x 
+                for x in configFiles ]
+
+gConfig.read(configFiles)
+
+# Dump loaded config if requested
+if configArgs.dump_config:
+    for section in gConfig.sections():
+        print section
+        for option in gConfig.options(section):
+            print " ", option, "=", gConfig.get(section, option)
+    sys.exit()
+
+
+
+#
+# Functional arguments go here
+#
+
+#
+# OVS target binaries -- these can all be specified individually. 
+# If not specified, they are determined by the base directory settings
+#
+gParser = argparse.ArgumentParser(parents=[gConfigParser])
+
+gParser.add_argument('--ovs-vswitchd-schema', 
+                     help="""Path to the vswitchd.ovsschema file""")
+gParser.add_argument('--ovs-vswitchd-log', 
+                     help="""Path to the vswitchd log file""")
+gParser.add_argument('--ovs-vswitchd-verbosity', 
+                     help="""Set vswitchd logging level (off/emer/err/warn/info/dbg)""",
+                     default="dbg")
+gParser.add_argument('--ovs-vswitchd', 
+                     help="""Path to the target ovs-vswitchd binary""")
+gParser.add_argument('--ovs-vsctl', 
+                     help="""Path to the target ovs-vsctl binary""")
+gParser.add_argument('--ovs-ofctl', 
+                     help="""Path to the target ovs-ofctl binary""")
+gParser.add_argument('--ovsdb-tool', 
+                     help="""Path to the target ovsdb-tool binary""")
+gParser.add_argument('--ovsdb-server', 
+                     help="""Path to the target ovsdb-server binary""")
+gParser.add_argument('--ovs-kmod', 
+                     help="""Path to the OVS kernel module""")
+gParser.add_argument('--ovs-src-dir',
+                     help="""Directory for the OVS Source Files""")
+
+gParser.add_argument('--ovs-log-dir',
+                     help="""Directory for the OVS Runtime Log Files""")
+
+gParser.add_argument('--ovs-version')
+
+gParser.add_argument("--ovs-base-dir", help="OVS Base Installation Directory")
+
+gParser.add_argument("--ovs-runtime-dir", 
+                     help="OVS Runtime Directory", 
+                     default="/var/run/ovs")
+
+gParser.add_argument('--ovs-db-sock', 
+                     help="Domain Socket Location")
+                     
+gParser.add_argument('--ovs-db-file', 
+                     help="Location for the OVS database file")
+
+
+#
+# Logging/Debugging/Testing options
+#
+gParser.add_argument('--dry', 
+                     help="""Dry run only. Don't actually do anything""", 
+                     action='store_true',  default=False)
+
+gParser.add_argument('--log', 
+                     help='Enable logging', 
+                     action='store_true', default=False)
+
+gParser.add_argument('--verbose', 
+                     help='Enable verbose output information', 
+                     action='store_true', default=False)
+
+gParser.add_argument("--kill", help="Kill running OVS", 
+                     default=False, action='store_true')
+
+gParser.add_argument("--keep-veths", 
+                     help="""By default, all existing veths will be destroyed and
+the veth module removed before initializing. If you don't want the veth module
+removed, specify this argument. Your mileage may vary if you use this.""", 
+                     default=False, action='store_true')
+
+gParser.add_argument("--no-kmod", 
+                     help="""Do not attempt to insert or remove the OVS kernel module. 
+Your mileage may vary.""", 
+                     default=False, action='store_true')
+
+gParser.add_argument("--vlog", 
+                     help="""Tail the running vswitch.log file in a new xterm""", 
+                     default=False, action='store_true')
+
+#
+# Runtime and setup arguments
+#
+gParser.add_argument('-p', '--port-count', type=int, 
+                     help="Number of veth ports to connect.", 
+                     default='4')
+
+
+gParser.add_argument("--bridge", help="Name of OF OVS Bridge", 
+                     default="ofbr0")
+
+gParser.add_argument("--cip", help="Controller Connection", 
+                     default="127.0.0.1")
+
+gParser.add_argument("--cport", type=int, help="Controller Port", 
+                     default=6653)
+gParser.add_argument("--dpid", help="DPID")
+
+gParser.add_argument("--max_backoff", help="VSwitchD max backoff value", 
+                     default=1000, type=int)
+
+
+gParser.add_argument("--keep-db", 
+                     help="""By default, a new database is initialized at each
+execution. If you want to keep and use the old database (if it exists), 
+use this option""", 
+                     action='store_true', default=False)
+
+gParser.add_argument('-lb', '--loopback',
+                     help="Create a loopback pair.  The port numbers are port_count+1 and port_count+2.", 
+                     default=False, action='store_true')
+
+
+gParser.add_argument("--cli", 
+                     help="Run the ovs-ctl cli after initialization", 
+                     action='store_true', default=False)
+
+gParser.add_argument("--teardown", 
+                     help="Kill OVS instance after CLI exits", 
+                     action='store_true', default=False)
+
+#
+# Reset defaults based on config files and override
+#
+# Anything in the "Defaults" section gets slurped first:
+defaults = {}
+if gConfig.has_section('Defaults'):
+    defaults = dict(gConfig.items('Defaults'))
+    gParser.set_defaults(**defaults)
+
+#
+# The configuration to execute might be specified in on the command line, or in the Defaults section(s)
+# of the config files. 
+#
+# If its specified on the command line, it will be present in configArgs.config
+# If its specified in the section, it will only be present in the defaults dict. 
+# Need to check both. Command line takes precedence. 
+#
+gConfigSection = None
+if configArgs.config != None:
+    gConfigSection = configArgs.config
+elif defaults.has_key('config'):
+    gConfigSection = defaults['config']
+
+
+if gConfigSection != None:
+    if gConfig.has_section(gConfigSection):
+        section = dict(gConfig.items(gConfigSection))
+        gParser.set_defaults(**section)
+    else:
+        print >>sys.stderr, "Requestion configuration '%s' does not exist" % (configArgs.config)
+        sys.exit()
+
+
+###############################################################################
+# 
+# Done with argument setup. Parser remaining arguments
+#
+###############################################################################
+gArgs = gParser.parse_args(remainingArgs)
+
+
+#
+# At the end of all of this, we need the following things to be defined
+# or derived:
+#
+gRequiredOptions = [
+    [ 'ovs_vswitchd_schema', 'ovs_src_dir',     '/vswitchd/vswitch.ovsschema', True,  True  ], 
+    [ 'ovs_vswitchd',        'ovs_base_dir',    '/sbin/ovs-vswitchd',          True,  True  ], 
+    [ 'ovs_vsctl',           'ovs_base_dir',    '/bin/ovs-vsctl',              True,  True  ], 
+    [ 'ovs_ofctl',           'ovs_base_dir',    '/bin/ovs-ofctl',              True,  True  ], 
+    [ 'ovsdb_tool',          'ovs_base_dir',    '/bin/ovsdb-tool',             True,  True, ], 
+    [ 'ovsdb_server',        'ovs_base_dir',    '/sbin/ovsdb-server',          True,  True, ], 
+    [ 'ovs_db_file',          'ovs_base_dir',    '/ovs.db',                    False, True, ], 
+    [ 'ovs_db_sock',         'ovs_runtime_dir', '/db.sock',                    False, True, ], 
+    [ 'ovs_kmod',            'ovs_base_dir',    '/sbin/openvswitch_mod.ko',    True,  not gArgs.no_kmod ], 
+]
+
+def __require_option(key, basedir, path, exists=True):
+    value = getattr(gArgs, key)
+    if value is None:
+        # Unspecified -- try to default based on given path
+        value = getattr(gArgs, basedir)
+
+        if value is None:
+            return False
+
+        value += path
+
+    if exists and not os.path.exists(value):
+        return False
+
+    if gArgs.verbose:
+        print '--v-- option: %s @ %s' % (key, value)
+
+    setattr(gArgs, key, value)
+
+
+Validated = True
+# Try to validate as many things as we can
+for option in gRequiredOptions:
+    if option[4]:
+        if __require_option(option[0], option[1], option[2], option[3]) == False:
+            Validated = False
+
+# If any of them failed, try to be as helpful as possible
+if Validated == False:
+    print >>sys.stdout, "\nConfiguration problem. One or more required settings are missing or could not be derived:\n"
+    for option in gRequiredOptions:
+        if option[4] is False:
+            continue
+
+        value = getattr(gArgs, option[0])
+        if value:
+            print >>sys.stdout, " %s: %s" % (option[0], value), 
+            if option[3] and not os.path.exists(value):
+                print >>sys.stdout, "-- does not exist"
+            else:
+                print "(OK)"
+        else:
+            print >>sys.stdout, " %s: Unknown. " % (option[0]), 
+            base = getattr(gArgs, option[1])
+            if base:
+                print >>sys.stdout, "Search path was '%s'." % (base + option[2])
+            else:
+                print >>sys.stdout, "Could not derive path because '%s' was also unspecified." % (option[1])
+    print >>sys.stdout
+    sys.exit()
+
+
+
+
+#
+# If we aren't in a dry run, you must execute as root to accompish anything
+#
+if not os.geteuid() == 0 and gArgs.dry == False:
+    print >>sys.stderr, "Must run as root to accomplish any of this."
+    sys.exit()
+
+
+###############################################################################
+#
+# Helpers 
+#
+###############################################################################
+
+def createVeths(count):
+    for idx in range(0, count):
+        lcall(["/sbin/ip", "link", "add", "type", "veth"])
+
+def vethsUp(count):
+    for idx in range(0, count*2):
+        lcall(["/sbin/ifconfig", 'veth%s' % (idx), "up"])
+
+def lcall(cmd, log=gArgs.log, dry=gArgs.dry, popen=False, 
+          pidFile=None):
+    
+    if log or gArgs.verbose:
+        print "%s: %s" % ('popen' if popen else 'call', cmd)
+    
+    if not dry:
+        if not popen:
+            subprocess.call(cmd)
+        else:
+            p = subprocess.Popen(cmd)
+            if pidFile != None:
+                pidf = open(pidFile, "w"); 
+                print >>pidf, p.pid
+                pidf.close()
+
+    
+
+def vsctl(argsList):
+    argsList.insert(0, "--db=unix:%s" % (gArgs.ovs_db_sock))
+    argsList.insert(0, gArgs.ovs_vsctl)
+    lcall(argsList)
+
+def ofctl(argsList):
+    argsList.insert(0, gArgs.ovs_ofctl)
+    lcall(argsList)
+
+def killpid(pid):
+    try:
+        os.kill(pid, signal.SIGTERM)
+        return False
+    except OSError, e:
+        return True
+
+
+def killp(pidfile):
+    if os.path.exists(pidfile):
+        pid=int(open(pidfile).read())
+        print "Killing %s, pid=%s..." % (pidfile, pid),
+        if not gArgs.dry:
+            while not killpid(pid):
+                time.sleep(1)
+                pass
+        print "dead"
+
+
+###############################################################################
+#
+# main
+#
+###############################################################################
+
+gServerPid = gArgs.ovs_runtime_dir + "/ovsdb-server.pid"
+gSwitchPid = gArgs.ovs_runtime_dir + "/ovs-vswitchd.pid"
+gLogPid=     gArgs.ovs_runtime_dir + "/ovs-vswitchd-tail.pid"
+
+# Kill previous execution based on contents of the runtime dir
+if os.path.exists(gServerPid):
+    print gServerPid
+    vsctl(["del-br", gArgs.bridge])
+
+
+def killall():
+    # Kill existing DB/vswitchd
+    killp(gSwitchPid)
+    killp(gServerPid)
+    killp(gLogPid)
+
+    # Remove old logpid file, since this does not happen automagically
+    if os.path.exists(gLogPid):
+        os.remove(gLogPid)
+
+    if gArgs.keep_veths == False:
+        lcall(['/sbin/rmmod', 'veth'])
+        lcall(['/sbin/modprobe', 'veth'])
+
+    # Remove kmod
+    lcall(['/sbin/rmmod', gArgs.ovs_kmod])
+
+
+killall()
+if gArgs.kill == True:
+    # Don't do anything else
+    sys.exit()
+
+
+# Remove bridge module
+lcall(['/sbin/rmmod', 'bridge'])
+# Insert openvswitch module
+lcall(['/sbin/insmod', gArgs.ovs_kmod])
+
+port_count = gArgs.port_count
+if gArgs.loopback:
+    port_count += 1
+createVeths(port_count)
+vethsUp(port_count)
+
+if not os.path.exists(gArgs.ovs_db_file) or gArgs.keep_db == False:
+    print "Initializing DB @ %s" % (gArgs.ovs_db_file)
+    if os.path.exists(gArgs.ovs_db_file) and not gArgs.dry:
+        os.remove(gArgs.ovs_db_file)
+
+    lcall([gArgs.ovsdb_tool, "create", gArgs.ovs_db_file, 
+           gArgs.ovs_vswitchd_schema])
+else:
+    print "Keeping existing DB @ %s" % (gArgs.ovs_db_file)
+
+
+if not os.path.exists(gArgs.ovs_runtime_dir):
+    os.makedirs(gArgs.ovs_runtime_dir)
+
+# Start dbserver
+lcall([gArgs.ovsdb_server, gArgs.ovs_db_file, 
+       "--remote=punix:%s" % (gArgs.ovs_db_sock), 
+       "--detach", "--pidfile=%s" % (gServerPid)])
+
+# Init db
+vsctl(["--no-wait", "init"])
+
+# Start vswitchd
+startV = [ gArgs.ovs_vswitchd, 
+          "unix:%s" % (gArgs.ovs_db_sock), 
+          "--verbose=%s" % gArgs.ovs_vswitchd_verbosity,
+          "--detach",
+          "--pidfile=%s" % (gSwitchPid) ]
+
+if gArgs.ovs_vswitchd_log:
+    startV.append("--log-file=%s" % (gArgs.ovs_vswitchd_log))
+
+lcall(startV)
+
+if gArgs.vlog:
+    lcall(["xterm", "-T", "vswitchd-log", "-e", "tail", "-f", 
+           gArgs.ovs_vswitchd_log], 
+          popen=True, pidFile=gLogPid)
+
+
+# Add a bridge
+vsctl(["add-br", gArgs.bridge])
+ofctl(["show", gArgs.bridge])
+
+# Add Veths to bridge
+for idx in range(0, gArgs.port_count):
+    vsctl(["add-port", gArgs.bridge, "veth%s" % (idx*2)])
+
+# Check if loopback port added
+if gArgs.loopback:
+    lb_idx = gArgs.port_count * 2
+    vsctl(["add-port", gArgs.bridge, "veth%d" % (lb_idx)])
+    vsctl(["add-port", gArgs.bridge, "veth%d" % (lb_idx+1)])
+
+if gArgs.dpid:
+    vsctl(["set", "bridge", gArgs.bridge, "other-config:datapath-id=%s" % (
+                gArgs.dpid)])
+
+# Set controller
+vsctl(["set-controller", gArgs.bridge, "tcp:%s:%s" % (
+        gArgs.cip, gArgs.cport)])
+
+# Minimize default backoff for controller connections
+vsctl(["set", "Controller", gArgs.bridge, 
+       "max_backoff=%s" % (gArgs.max_backoff)])
+
+
+ofctl(["show", gArgs.bridge])
+
+
+if gArgs.cli:
+    while True:
+        cmd = raw_input("[%s] ovs-ctl> " % gConfigSection)
+        if cmd and cmd != "":
+            args = cmd.split(" ")
+            if args[0] == "vsctl" or args[0] == "ovs-vsctl":
+                vsctl(args[1:])
+            elif args[0] == "ofctl" or args[0] == "ovs-ofctl":
+                ofctl(args[1:])
+            elif args[0] == "dumpflows" or args[0] == "flowtable":
+                ofctl(["dump-flows", "%s" % gArgs.bridge])
+            elif args[0] == "exit" or args[0] == "quit":
+                break; 
+            elif args[0] == "kill":
+                gArgs.teardown = True
+                break
+            else:
+                print "unknown command '%s'" % args[0]
+            
+
+if gArgs.teardown:
+    print "Killing OVS"
+    killall()
+
+
+
+
+                        
+